Android12

Android12

计算机图形的表示方法

位图

一个一个像素点

算法:

位图图形的大小=位图的宽度 * 位图的高度 * 每一个像素点占据字节数
位图的宽度 * 位图的高度 是分辨率

BMP的格式:

单色位图 1个bit byte = 1/8

16色位图 4个bit byte = 4/8

256色位图 8个bit byte = 8/8

24位位图 24个bit byte = 24/8

矢量图

根据比例

加载图片到内存

public void loadImage(View view){
    //加载一个图片到内存 显示到imageview的控件上.
    Bitmap bitmap = BitmapFactory.decodeFile("mnt/sdcard/big.jpg");
    //32位的位图, argb 
    iv.setImageBitmap(bitmap);
}

--------------------------------------
BitmapFactory.decodeStream(is);(最多用)


BitmapFactory.decodeFile("mnt/sdcard/big.jpg");(次多用(getFiles(),getcache(),SDcard中范围))


BitmapFactory.decodeResource(res, id);(相对少)

Android下面的位图默认是32位
ARGB : alpha red green blue 每一个是8位

图片需要加载内存的大小(1.6M在硬盘) = 宽度 * 高度 * (32/8)(内存中15.4M)

加载大图片到内存

//加载一个图片到内存 显示到imageview的控件上.
Options opts = new Options();//创建一个选项条件
opts.inSampleSize = 4;//设置采样率,宽高分别是原图的1/4,总像素个数就变成原图的1/16
Bitmap bitmap = BitmapFactory.decodeFile("mnt/sdcard/big.jpg", opts);
//32位的位图, argb 
iv.setImageBitmap(bitmap);

//1.得到图片的宽高信息.
ExifInterface exif = new ExifInterface("mnt/sdcard/big.jpg");
int width = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
int height = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
System.out.println("widtH:"+width);
System.out.println("height:"+height);

//2.获取屏幕的宽高
WindowManager  wm = (WindowManager) getSystemService(WINDOW_SERVICE);
int screenWidth = wm.getDefaultDisplay().getWidth();
int screenHeight = wm.getDefaultDisplay().getHeight();
System.out.println("屏幕width:"+screenWidth);
System.out.println("屏幕height:"+screenHeight);

图片的缩放

public void processImage(View view){
    //得到原始位图的对象
    Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/tu1.jpg");
    iv_src.setImageBitmap(srcBitmap);
    //缩放后 显示一个缩放后的图片 在iv_dest
    //用代码编辑图片,最好处理都是图片在内存中的拷贝,不去处理原图.
    Bitmap copyedBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
    //临摹.创建一个画板
    Canvas canvas = new Canvas(copyedBitmap);
    //创建画笔
    Paint paint = new Paint();
    paint.setColor(Color.BLACK);
    //作画
    Matrix matrix = new Matrix();//按照1:1的比例作画
    matrix.setScale(0.6f, 0.6f);
    canvas.drawBitmap(srcBitmap, matrix, paint);
    iv_dest.setImageBitmap(copyedBitmap);

}

图片的平移旋转镜面和倒影效果

//平移
Bitmap copyedBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
//临摹.创建一个画板
Canvas canvas = new Canvas(copyedBitmap);
//创建画笔
Paint paint = new Paint();
paint.setColor(Color.BLACK);
//作画
Matrix matrix = new Matrix();//按照1:1的比例作画

matrix.setTranslate(100, 100);

canvas.drawBitmap(srcBitmap, matrix, paint);
iv_dest.setImageBitmap(copyedBitmap);

//旋转
Bitmap copyedBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
//临摹.创建一个画板
Canvas canvas = new Canvas(copyedBitmap);
//创建画笔
Paint paint = new Paint();
paint.setColor(Color.BLACK);
//作画
Matrix matrix = new Matrix();//按照1:1的比例作画

matrix.setRotate(180, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);

canvas.drawBitmap(srcBitmap, matrix, paint);
iv_dest.setImageBitmap(copyedBitmap);

//镜面
Canvas canvas = new Canvas(copyedBitmap);
//创建画笔
Paint paint = new Paint();
paint.setColor(Color.BLACK);
//作画
Matrix matrix = new Matrix();//按照1:1的比例作画

matrix.setScale(-1, 1);
matrix.postTranslate(srcBitmap.getWidth(), 0);

canvas.drawBitmap(srcBitmap, matrix, paint);
iv_dest.setImageBitmap(copyedBitmap);

//倒影
Bitmap copyedBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
//临摹.创建一个画板
Canvas canvas = new Canvas(copyedBitmap);
//创建画笔
Paint paint = new Paint();
paint.setColor(Color.BLACK);
//作画
Matrix matrix = new Matrix();//按照1:1的比例作画

matrix.setScale(1, -1);
matrix.postTranslate(0, srcBitmap.getHeight());

canvas.drawBitmap(srcBitmap, matrix, paint);
iv_dest.setImageBitmap(copyedBitmap);

随手涂鸦的ui

  • view水平方向线性布局

  • 拖动条SeekBar

  • ImageView

    // 设置画笔的颜色
    paint.setColor(Color.BLACK);
    
    
    // 设置画笔的宽度
    paint.setStrokeWidth(5);
    

随手涂鸦的核心逻辑

触摸事件的操作:

iv.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:// 按下
            case MotionEvent.ACTION_MOVE:// 移动
            case MotionEvent.ACTION_UP:// 离开
        return true;
        //false代表的是事件没有处理完毕,等待事件处理完毕, true代表事件已经处理完毕了.

    }
}

System.out.println("摸到");
startX = (int) event.getX();
startY = (int) event.getY();

System.out.println("移动");
int newX = (int) event.getX();
int newY = (int) event.getY();

//画直线
canvas.drawLine(startX, startY, newX, newY, paint);
iv.setImageBitmap(alterBitmap);


// 记得重新初始化手指在屏幕上的坐标
startX = (int) event.getX();
startY = (int) event.getY();

随手涂鸦的细节

File file = new File(Environment.getExternalStorageDirectory(),
        SystemClock.currentThreadTimeMillis() + ".jpg");
FileOutputStream stream = new FileOutputStream(file);

------------------------------------------  
//保存图片的API,格式,质量,输出流sdcard位置
alterBitmap.compress(CompressFormat.JPEG, 100, stream);



//欺骗系统,插入SDcard的广播
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
sendBroadcast(intent);


<!-- 写入SDcard的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

撕衣服

    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            x = (int) event.getX();
            y = (int) event.getY();
            for(int i=-3;i<4;i++){
                for(int j=-3;j<4;j++){
                    if(Math.sqrt(i*i+j*j)<=3){
                        try {
                            alterBitmap.setPixel(x+i, y+j, Color.TRANSPARENT);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            iv_pre.setImageBitmap(alterBitmap);
            break;
        case MotionEvent.ACTION_MOVE:
            x = (int) event.getX();
            y = (int) event.getY();
            for(int i=-3;i<4;i++){
                for(int j=-3;j<4;j++){
                    if(Math.sqrt(i*i+j*j)<=3){
                        try {
                            alterBitmap.setPixel(x+i, y+j, Color.TRANSPARENT);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            iv_pre.setImageBitmap(alterBitmap);
            break;
        case MotionEvent.ACTION_UP:

            break;
        }
        return true;// 事件结束被消费掉了
    }
});

getX和getRawX区别

getX到控件的距离

getRawX到屏幕的距离

图片的颜色处理

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    sb_red = (SeekBar) findViewById(R.id.sb_red);
    iv = (ImageView) findViewById(R.id.iv);
    sb_red.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            int progress = seekBar.getProgress();
            float result = progress/50.0f;
            System.out.println("变化的百分比为:"+result);
            ColorMatrix cm = new ColorMatrix();
            cm.set(new float[] {
                1*result, 0, 0, 0, 0,
                0, 1, 0, 0, 0,
                0, 0, 1, 0, 0,
                0, 0, 0, 1, 0
            });
            paint.setColorFilter(new ColorMatrixColorFilter(cm));
            canvas.drawBitmap(srcBitmap, new Matrix(), paint);
            iv.setImageBitmap(copyedBitmap);
        }              
    });

音乐播放器的状态图

mediaPlayer = new MediaPlayer();
final ProgressDialog pd = new ProgressDialog(this);
pd.setMessage("正在缓冲...");
mediaPlayer.reset();
//设置播放的文件
mediaPlayer.setDataSource(et_path.getText().toString().trim());

mediaPlayer.prepare();//同步的准备
pd.show();
mediaPlayer.setOnErrorListener(new OnErrorListener() {

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        Toast.makeText(MainActivity.this, "播放失败,错误代码:"+what, 0).show();
        return false;
    }
});


public void pause(View view) {
    if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
        mediaPlayer.pause();
        return;
    }
    if(mediaPlayer!=null){
        mediaPlayer.start();
    }
}

public void stop(View view) {
    if(mediaPlayer!=null){
        mediaPlayer.stop();
        mediaPlayer.release();
        mediaPlayer = null;
    }
}

异步播放网络上的音乐文件

mediaPlayer.prepareAsync();//异步的准备,开启子线程去准备

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        pd.dismiss();
        mediaPlayer.start();
    }
});

soundpool

打篮球的声音是用soundpool做的,不是mediaPlayer

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    soundPool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0);
    soundID = soundPool.load(this, R.raw.shoot, 1);
}

public void click(View view){
    soundPool.play(soundID, 1.0f, 1.0f, 0, 0, 1.0f);
}

视频播放器

protected void onCreate(Bundle savedInstanceState) {   
  VideoView vv  vv = (VideoView) findViewById(R.id.vv);
    vv.setVideoPath("/mnt/sdcard/oppo.3gp");
    MediaController mc = new MediaController(this);
    //设置控制器 控制的是那一个videoview
    mc.setAnchorView(vv);
    //设置videoview的控制器为mc
    vv.setMediaController(mc);
    vv.start();
}

SurfaceView子线程更新ui

/**
 * 演示SurfaceView控件的使用
 * SurfaceView 单位时间内完成界面的大量多次更新
 * 双缓冲机制 :
 * A线程----更新ui -----后台计算---更新ui
 * B线程----后台计算----更新ui  ---后台计算
 * 可以在子线程更新ui
 */

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="click"
    android:text="开启子线程更新ui" />

<SurfaceView
    android:id="@+id/sv"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

surfaceview生命周期的回调

sv = (SurfaceView) findViewById(R.id.sv);
//注册一个surfaceview控制器的回调
sv.getHolder().addCallback(new Callback() {

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        System.out.println("surface被销毁了");
        flag = false;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        System.out.println("surface创建了");
        flag = true;
        new Thread(){
            public void run() {
                for(int i = 0;i<100;i++){
                    if(!flag){
                        return ;
                    }
                //界面里面内容显示的控制器
                    SurfaceHolder holder = sv.getHolder();
                    Canvas  canvas = holder.lockCanvas();
                    canvas.drawColor(Color.BLACK);
                    int radius = 5+i;
                    Paint paint = new Paint();
                    paint.setColor(Color.RED);
                    canvas.drawCircle(250, 250, radius, paint);
                    holder.unlockCanvasAndPost(canvas);
                    SystemClock.sleep(100);
                }
            };
        }.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        System.out.println("surface大小发生了变化");
    }
});

采用surfaceview播放视频

<SurfaceView
    android:id="@+id/sv"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

@Override
public void surfaceCreated(SurfaceHolder holder) {
    System.out.println("surface被创建");
    try {
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setDataSource("/mnt/sdcard/oppo.3gp");
        mediaPlayer.prepare();
    } catch (Exception e) {
        e.printStackTrace();
    }
    //指定多媒体的内容实在holder里面显示
    mediaPlayer.setDisplay(holder);
    mediaPlayer.start();
    mediaPlayer.seekTo(sp.getInt("position", 0));
}


@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    System.out.println("surface被销毁");
    if(mediaPlayer!=null){
        int position = mediaPlayer.getCurrentPosition();
        Editor editor  = sp.edit();
        editor.putInt("position", position);
        editor.commit();
        mediaPlayer.stop();
        mediaPlayer.release();
    }
}

照相机拍照

public void takePic(View view){
    //开启手机的照相机应用拍照获取返回值
     // create Intent to take a picture and return control to the calling application
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    file = new File(Environment.getExternalStorageDirectory(),SystemClock.uptimeMillis()+".jpg"); // create a file to save the image
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // set the image file name

    // start the image capture Intent
    startActivityForResult(intent, 0);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(file!=null&&file.exists()&&file.length()>0){
        System.out.println(file.getAbsolutePath());
        ImageView iv = (ImageView) findViewById(R.id.iv);
        iv.setImageURI(Uri.fromFile(file));
    }
    super.onActivityResult(requestCode, resultCode, data);
}

视频的录制

public void takePic(View view){
    //开启手机的照相机应用拍照获取返回值
     // create Intent to take a picture and return control to the calling application
    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

    file = new File(Environment.getExternalStorageDirectory(),SystemClock.uptimeMillis()+".3gp"); // create a file to save the image
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // set the image file name

    // start the image capture Intent
    startActivityForResult(intent, 0);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(file!=null&&file.exists()&&file.length()>0){
        System.out.println(file.getAbsolutePath());
        VideoView vv= (VideoView) findViewById(R.id.vv);
        vv.setVideoPath(file.getAbsolutePath());
        MediaController mc = new MediaController(this);
        mc.setAnchorView(vv);
        vv.setMediaController(mc);
        vv.start();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

传感器的使用

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    sm = (SensorManager) getSystemService(SENSOR_SERVICE);
    //得到光传感器
    Sensor sensor = sm.getDefaultSensor(Sensor.TYPE_LIGHT);
    listener = new MyListnener();
    sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}

private class MyListnener implements SensorEventListener{
    //当传感器数据变化的调用的方法
    @Override
    public void onSensorChanged(SensorEvent event) {
        float light = event.values[0];
        System.out.println("光线强度:"+light);
    }
    //当传感器精度发生变化的时候调用的方法
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}
@Override
protected void onDestroy() {
    sm.unregisterListener(listener);
    listener = null;
    super.onDestroy();
}

指南针

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    sm = (SensorManager) getSystemService(SENSOR_SERVICE);
    //得到方向传感器
    Sensor sensor = sm.getDefaultSensor(3);
    listener = new MyListnener();
    sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}

private class MyListnener implements SensorEventListener{
    //当传感器数据变化的调用的方法
    @Override
    public void onSensorChanged(SensorEvent event) {
        //values[0]: 地磁北极和手机y轴的夹角,  0=北, 90=东, 180=南, 270=西 
        int angle = (int) event.values[0];
        if(angle>0&&angle<90){
            System.out.println("东北");
        }else if (angle>90&&angle<180){
            System.out.println("东南");
        }else if(angle>180&&angle<270){
            System.out.println("西南");
        }else if(angle>270&&angle<360){
            System.out.println("西北");
        }else if(angle==0){
            System.out.println("北");
        }else if(angle==90){
            System.out.println("东");
        }else if(angle==180){
            System.out.println("南");
        }else if(angle==270){
            System.out.println("西");
        }
    }
    //当传感器精度发生变化的时候调用的方法
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}
@Override
protected void onDestroy() {
    sm.unregisterListener(listener);
    listener = null;
    super.onDestroy();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值