首页 > 移动平台 > 详细

Android之多媒体编程

时间:2015-11-10 22:20:15      阅读:324      评论:0      收藏:0      [点我收藏+]

多媒体的概念:

  文字、图片、音频、视频

图片

  常见的图片格式:

    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); } }

  


 

 

安卓开发者,产品爱好者

个人微博

 

     

 

Android之多媒体编程

原文:http://www.cnblogs.com/jiaowoxiaochen/p/4954388.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!