图片大小
- 图片在计算机中的大小
- 图片的总大小 = 图片的总像素 * 每个像素占用的大小
位图
bmp格式的图片是无损压缩,严格按照算法来计算图片大小;jpg格式的图片是有损压缩。
2016/9/19 18:24:20
- 单色位图:只能表示2种颜色
- 使用两个数字:0和1
- 使用一个长度为1的二进制数字就可以表示了
- 每个像素占用1/8个字节
- 16色位图:能表示16种颜色
- 需要16个数字:0-15,0000 - 1111
- 使用一个长度为4的二进制数组就可以表示了
- 每个像素占用1/2个字节
- 256色位图:能表示256种颜色
- 需要256个数字:0 - 255,0000 0000 - 1111 1111
- 使用一个长度为8的二进制数字
- 每个像素占用1个字节
- 24位位图:
- 每个像素占用24位,也就是3个字节,所在叫24位位图
- R:0-255,需要一个长度为8的二进制数字,占用1个字节
- G:0-255,需要一个长度为8的二进制数字,占用1个字节
- B:0-255,需要一个长度为8的二进制数字,占用1个字节
对图片进行缩放
-
获取屏幕宽高
Display dp = getWindowManager().getDefaultDisplay(); int screenWidth = dp.getWidth(); int screenHeight = dp.getHeight();
-
获取图片宽高
Options opts = new Options(); //请求图片属性但不申请内存 opts.inJustDecodeBounds = true; BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/dog.jpg", opts); int imageWidth = opts.outWidth; int imageHeight = opts.outHeight;
-
图片的宽高除以屏幕宽高,算出宽和高的缩放比例,取较大值作为图片的缩放比例
int scale = 1; int scaleX = imageWidth / screenWidth; int scaleY = imageHeight / screenHeight; if(scaleX >= scaleY && scaleX > 1){ scale = scaleX; } else if(scaleY > scaleX && scaleY > 1){ scale = scaleY; }
-
按缩放比例加载图片
//设置缩放比例 opts.inSampleSize = scale; //为图片申请内存 opts.inJustDecodeBounds = false; Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/dog.jpg", opts); iv.setImageBitmap(bm);
在内存中创建图片的副本
直接加载的bitmap对象是只读的,无法修改,要修改图片只能在内存中创建出一个一模一样的bitmap副本,然后修改副本
-
加载原图
Bitmap bmSrc = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/jietu.jpg");
-
在内存中创建一个与原图一模一样大小的bitmap对象<一张白纸>(可读可写)
Bitmap bitmap = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());
-
创建画笔对象
Paint paint = new Paint();
-
创建画板对象,将白纸铺在画板上
Canvas canvas = new Canvas(bitmap);
-
开始作画,把原图的内容绘制在白纸上
canvas.drawBitmap(bmSrc, new Matrix(), paint);
简单绘图
-
绘图需要用到触摸侦听事件,需要给画画板设置触摸侦听事件
/*给画画板设置触摸侦听事件*/ imageView.setOnTouchListener(new OnTouchListener() { /*触摸事件产生时,此方法调用*/ @Override public boolean onTouch(View v, MotionEvent event) { /*拿到触摸屏幕对象现在所处的状态*/ int action = event.getAction(); switch (action) { /*用户手指触摸到屏幕*/ case MotionEvent.ACTION_DOWN: Log.d("MainActivity", "触摸屏幕"); break; /*用户手指正在滑动,此方法会被不断调用*/ case MotionEvent.ACTION_MOVE: Log.d("MainActivity", "滑动屏幕" + x + " " + y); break; /*用户手指离开屏幕,此方法调用*/ case MotionEvent.ACTION_UP: Log.d("MainActivity", "离开屏幕"); break; } /*此处返回true表示用户手动处理事件*/ return true; } });
-
画笔对象改变线条粗细
paint.setStrokeWidth(float width);
-
画笔对象改变线条颜色
paint.setColor(int color);
-
保存画画板图像,通过
Bitmap
对象的方法来实现保存功能/* * format:保存的格式 * quality:保存质量,(0-100. 0)数字越大质量越高 * stream:输出流 * compress(CompressFormat format, int quality, OutputStream stream) */ bitmap.compress(CompressFormat.PNG, 100, stream);
-
从图库中立即查看到保存的图片
直接将图片保存,接着打开图库是不能看到图片信息的。系统每次收到SD卡就绪广播时,都会去遍历sd卡的所有文件和文件夹,把遍历到的所有多媒体文件都在MediaStore数据库保存一个索引,这个索引包含多媒体文件的文件名、路径、大小。图库每次打开时,并不会去遍历sd卡获取图片,而是通过内容提供者从MediaStore数据库中获取图片的信息,然后读取该图片。故我们将图片保存起来以后,需要手动发送一条SD卡就绪广播,这样MediaStore数据库中就添加进所保存图片的索引。Intent intent = new Intent(); intent.setAction(Intent.ACTION_MEDIA_MOUNTED); /*设置data属性*/ intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory())); /*发送广播*/ sendBroadcast(intent);