多媒体的概念:
文字、图片、音频、视频
图片
常见的图片格式:
png:无损保存图片,高质量的图片,.BMP格式保存的图像质量不变,文件也比较大,因为要保存每个像素的信息.
JPEG――是一种较常用的有损压缩图片,文件压缩变小,不保存每个像素的信息。
PNG--压缩不失真,它综合了JPG和GIF格式的优点
GIF―是一种图像交换格式,可提供压缩功能,但只支持256色,很少用于照片级图像处理工作.在PhotoShop中把对颜色数要求不高的图片变为索引色,再以GIF格式保存,使文件缩小后用更快的速度在网上传输.
单色位图:只能表示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位位图 1600多万种
R:0-255,需要一个长度为8的二进制数字,占用1个字节
G:0-255,需要一个长度为8的二进制数字,占用1个字节
B:0-255,需要一个长度为8的二进制数字,占用1个字节
图片在计算机中的大小
图片的总大小 = 图片的总像素 * 每个像素占用的大小
加载大图片
计算机把图片所有像素信息全部解析出来,保存至内存
Android保存图片像素信息,是用ARGB保存 ,所以每个像素占用4个字节,很容易内存溢出。
在安卓程序中,加载大图片可以采用缩放的方式。
原理:第一步 :在解析图片的时候,我们使用位图工厂的api BitmapFactory.decodeFile(pathName, opts) ,在这个api中可以传入一个Options的对象,而我们解析图片时所需要的参数都封装进这个api中,把Options对象的inJustDecodeBounds的属性设为 true,通过文档可知,这样通过位图工场解析图图片,不会反悔位图,也不会为图像的像素申请内存。 =
第二步:通过Options对象拿到图片的宽高opt.outWidth;opt.outHeight; getWindowManager().getDefaultDisplay();拿到手机屏幕返回一个Display对象,通过display对象获得屏幕的宽高getWidth() getHeight();
第三步:拿图片的像素除以屏幕的像素,取大的值作为缩放比例,然后给options对象的inSampleSize属性设置缩放比例 再将opt.inJustDecodeBounds = false;这时候通过位图工厂解析图片,传入的options对象所需要解析的参数,就是我们需要的图片。
代码体现:
public void click(View v) { //位图工场解析图片的参数封装在Options对象中 Options opts = new Options(); //不为像素申请内存,不返回位图对象 opts.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(),R.drawable.person,opts); //拿到图片宽高 int imageHeight = opts.outHeight; int imageWidth = opts.outWidth; //拿到手机屏幕 Display dis = getWindowManager().getDefaultDisplay(); //获得手机屏幕的宽高 int screenHeight = dis.getHeight(); int screenWidth = dis.getWidth(); //计算缩放比例 int scale = 1; int scaleHeight = imageHeight / screenHeight; int scaleWidth = imageWidth / screenWidth; if(scaleHeight >= scaleWidth && scaleHeight >= 1) { scale = scaleHeight; }else if(scaleWidth>=scaleHeight && scaleWidth>=1) { scale = scaleWidth; } //设置缩放属性 opts.inSampleSize = scale; opts.inJustDecodeBounds = false; Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.person,opts); ImageView iv = (ImageView) findViewById(R.id.iv); iv.setImageBitmap(bm); }
在内存中创建图片的副本
由于我们直接加载的bitmap对象是只读的,我们无法对其做一些修改,要修改图片只能在内存中创建出一个一模一样的bitmap副本,然后修改副本
思路:第一步通过位图工厂拿到位图对象
第二步.在内存中创建一个与原图一模一样大小的bitmap对象,创建与原图大小一致的白纸Bitmap.createBitmap()
第三 步 创建画笔对象Paint
第四步 .创建画板对象,把白纸铺在画板上Canvas
第四步 开始作画,把原图的内容绘制在白纸上canvas.drawBitmap
代码 : 在两个imageView中通过创建图片副本,显示两个一样的图片
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Bitmap bt = BitmapFactory.decodeResource(getResources(), R.drawable.person); //创建一个与原图一样大小的白纸 Bitmap btCopy = Bitmap.createBitmap(bt.getWidth(), bt.getHeight(), bt.getConfig()); Paint pt = new Paint(); //创建画板对象,把白纸铺在画板上Canvas Canvas cv = new Canvas(btCopy); //4.开始作画,把原图的内容绘制在白纸上 cv.drawBitmap(bt, new Matrix(), pt); ImageView iv_bitmap = (ImageView) findViewById(R.id.iv1); ImageView iv_copyMap = (ImageView) findViewById(R.id.iv2); iv_bitmap.setImageBitmap(bt); iv_copyMap.setImageBitmap(btCopy); } }
通过图片副本完成画画板的案例
需求: 在activity上有一块画板 画板下方有四个Button 分别可以设置画笔的颜色为红色 绿色 设置画笔变粗 保存图片(保存的图片可以在安卓自带的图片应用中查看)
思路: 第一步 加载画画板的背景图
第二步 通过图片副本 创建一个与背景图一样的画板 显示在imageView上
第三步 由于我们在画板上作画。通过我们在屏幕上触摸移动,把我们触摸到的像素位置设置颜色。 所以我们需要给图片设置触摸侦听(setOnTouchListener)
在我们触摸屏幕时会触发onTouch方法,手指在屏幕上触摸有三种情况 分别为MotionEvent.ACTION_DOWN 手指摸到屏幕 MotionEvent.ACTION_MOVE手指在滑动 MotionEvent.ACTION_UP:
第四步 我们在手指摸到屏幕的时候记录位置,在手指移动的时候记录每次移动的位置,把每次移动的位置和手指触摸屏幕的位置之间划线drawLine 注意是每次绘制完毕之后,本次绘制的结束坐标变成下一次绘制的初始坐标,画完后将绘制后的图片设置到imageView
(监听事件内部类的返回值问题
true:告诉系统,这个触摸事件由我来处理
false:告诉系统,这个触摸事件我不处理,这时系统会把触摸事件传递给imageview的父节点
)
第五步 改变颜色 就是给画笔设置颜色
第六步 画笔加粗可以调用画笔setStrokeWidth(); 传入int 数值给画笔设置粗细
第七步 保存图片 调用bitmap的方法compress 可以保存图片
第八步 我们需要在保存图片的时候,就可以在系统的图片应用中看到图片 ,系统每次收到SD卡就绪广播时,都会去遍历sd卡的所有文件和文件夹,把遍历到的所有多媒体文件都在MediaStore数据库保存一个索引,这个索引包含多媒体文件的文件名、路径、大小。 图库每次打开时,并不会去遍历sd卡获取图片,而是通过内容提供者从MediaStore数据库中获取图片的信息,然后读取该图片,系统开机或者点击加载sd卡按钮时,系统会发送sd卡就绪广播,我们也可以手动发送就绪广播
代码:
public class MainActivity extends Activity { private Canvas cancas; private Paint paint; private ImageView iv_drawBoard; private Bitmap bt_copy; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
//使用图片副本拿到可修改的副本图片 Bitmap bt = BitmapFactory.decodeResource(getResources(), R.drawable.bg); bt_copy = Bitmap.createBitmap(bt.getWidth(), bt.getHeight(), bt.getConfig()); paint = new Paint(); cancas = new Canvas(bt_copy); cancas.drawBitmap(bt, new Matrix(), paint); iv_drawBoard = (ImageView) findViewById(R.id.iv_drawBoard); iv_drawBoard.setImageBitmap(bt_copy);
//设置触摸监听 iv_drawBoard.setOnTouchListener(new OnTouchListener() { private int startX; private int startY; //完成滑动画笔功能 @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN : startX = (int) event.getX(); startY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE : int X = (int) event.getX(); int Y = (int) event.getY(); cancas.drawLine(startX, startY, X, Y, paint); startX = X; startY = Y; iv_drawBoard.setImageBitmap(bt_copy); break; case MotionEvent.ACTION_UP : break; } return true; } }); } //改变画笔颜色 public void click_red(View v) { paint.setColor(Color.RED); } public void click_green(View v) { paint.setColor(Color.GREEN); }
//改变画笔粗细 public void click_rough(View v) { paint.setStrokeWidth(7); }
//将图片保存 public void click_save(View v) { File file = new File(Environment.getExternalStorageDirectory(), "dazuo.PNG"); FileOutputStream stream = null; try { stream = new FileOutputStream(file); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }
//位图对象的compress方法可以保存图片 bt_copy.compress(CompressFormat.PNG, 100, stream);
//如果需要在图片应用看到图片,需要在保存图片之后发送广播,告知系统去遍历sd卡,把图片添加到MediaStore数据库 Intent intent = new Intent(); intent.setAction(Intent.ACTION_MEDIA_MOUNTED); intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory())); sendBroadcast(intent); } }
安卓开发者,产品爱好者
个人微博
原文:http://www.cnblogs.com/jiaowoxiaochen/p/4954388.html