Android 多媒体编程

1、大图片的加载:
图片在计算机中的大小
* 图片的总大小 = 图片的总像素 * 每个像素占用的大小
* 单色位图:只能表示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个字节

加载大图片

  • 计算机把图片所有像素信息全部解析出来,保存至内存
  • Android保存图片像素信息,是用ARGB保存 a 透明度
  • 手机屏幕320*480,总像素:153600
  • 图片宽高2400*3200,总像素7680000
  • 2400 / 320 = 7
  • 3200 / 480 = 6
    比例选择是7 比例选择是6的话图片宽度还是会溢出屏幕宽度。

代码:
options 中保存着许多选项的。 解析图片时所需的参数都在options 对象之中。


    public void click(View v) {
        // 选项 解析图片时所需的参数都在options 对象之中。
        Options opt = new Options();   
        // 只解析边界。
        opt.inJustDecodeBounds = true;   
         BitmapFactory.decodeFile("sdcard/dog.jpg", opt);
        int imageWidth = opt.outWidth;
        int imageHeight = opt.outHeight;
        Display dp = getWindowManager().getDefaultDisplay();
        int ScreenWidth = dp.getWidth();
        int ScreenHeight = dp.getHeight();
        // 计算屏幕的缩放比例;
        int scale = 1;

        int scaleWidth = imageWidth / ScreenWidth;
        int scaleHeight = imageHeight / ScreenHeight;

        if (scaleWidth > scaleHeight && scaleWidth >= 1) {  //判断比例哪个大,就用哪个。

            scale = scaleWidth;

        } else if (scaleHeight > scaleWidth && scaleHeight >= 1) {
            scale = scaleHeight;
        }

        // 设置缩放比例:

        opt.inSampleSize = scale;
        opt.inJustDecodeBounds = false;  //设置好比例之后,记得将只解析边界置为false.

        Bitmap bm= BitmapFactory.decodeFile("sdcard/dog.jpg", opt);  //用位图工厂解析图片此时图片就在bm中。
        ImageView iv = (ImageView) findViewById(R.id.iv);
        iv.setImageBitmap(bm);  //设置图片显示。
    }

创建图片的副本:
也就是copy,
//这个Bitmap对象是只读的。
Bitmap bm= BitmapFactory.decodeFile(“sdcard/zhuzi.jpg”);
先创建一张白纸:也是跟这个图片的尺寸一样的;
2、创建画笔
3、创建画板,把白纸铺上去。
4、作画。。。

    Bitmap  bm= BitmapFactory.decodeFile("sdcard/zhuzi.jpg");

        //得到一个位图对象和bm的尺寸一样, 相当于画图的白纸。
        Bitmap  bmcopy=  Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig());  //用位图对象创建,一张跟原图一样尺寸的     白纸
        //创建画笔;
        Paint  paint= new Paint();
        //创建画板;
        Canvas  cavas =new Canvas(bmcopy);
        cavas.drawBitmap(bm, new Matrix(), paint);   //在画板上开始作画,做的model也就是原来的位图。
        ImageView iv = (ImageView) findViewById(R.id.iv_org);
        ImageView iv_copy =(ImageView) findViewById(R.id.iv_copy);
        iv.setImageBitmap(bm);
        iv_copy.setImageBitmap(bmcopy);

简单特效:
平移,缩放。

Matrix mt= new Matrix(); //矩阵。

//平移

// mt.setTranslate(20, 40); 平移。
//缩放 x,y是缩放比例。 1表示不变。
mt.setScale(0.5f, 0.5f); //这个缩放是以左上角为缩放点缩放的。
mt.setScale(0.5f,0.5f, bm.getWidth()/2,bm.getHeight()/2); //这个是以中心点为中心进行缩小的。
//设置旋转
mt.setRotate(45);
//围绕中心旋转45度角。
用的比较多的是镜面和倒影;
镜面:也就是图片的宽高不变,x轴方向加个负号就可以了。
mt.setRotate(45, bmcopy.getWidth()/2, bmcopy.getHeight()/2);
cavas.drawBitmap(bm, mt, paint);
注意的是:
对于有两种效果的,第一个用set第二种用post设置。

//镜面效果。 
平移之后x移出平面位置所以平移回来就可以,y轴方向不变。
        mt.setScale(-1, 1);
        mt.postTranslate(bmcopy.getWidth(), 0);

倒影:
就是x方向保持不变,Y方向给个负数,

//倒影效果
        mt.setScale(1, -1);
        mt.postTranslate(0, bmcopy.getHeight());

触摸侦听:
ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setOnTouchListener(new OnTouchListener){ //设置触摸侦听。

        @Override // 触摸时该方法调用。
        public boolean onTouch(View v, MotionEvent event) {  
            // TODO Auto-generated method stub
            int action = event.getAction();
            switch (action) {
            //用户手指触摸到屏幕
            case MotionEvent.ACTION_DOWN:
               System.out.println("用户手指触摸屏幕");
                break;
            //用户手指抬离屏幕
            case MotionEvent.ACTION_UP:
                System.out.println("手指离开屏幕");

                break;
                //用户手指正在滑动。
            case MotionEvent.ACTION_MOVE:
                System.out.println("手指在移动");

                break;


            }
            //true:告诉系统这个事件由这个组件自己处理。
            //false:告诉系统这个事件它自己处理,抛出去交给父类。
            return true;
        }

    });

创建画板作画;

package com.zh.paintplate;

import android.app.Activity;
import android.app.Notification.Action;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private Canvas canvas;

    private int startx;
    private int starty;

    private Paint paint;

    private Bitmap bmcopy;

    private ImageView iv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获得Bitmap对象通过资源id的形式。
        Bitmap  bm = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
        bmcopy = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),bm.getConfig());
        paint = new Paint();
        canvas = new Canvas(bmcopy);  //            创建画板,铺上白纸。白纸一定要加上不然的话界面不显示图片。
        //绘制图片
        canvas.drawBitmap(bm, new Matrix(),  paint);



        iv = (ImageView) findViewById(R.id.iv);

        iv.setImageBitmap(bmcopy);

        // 设置触摸监听。
        iv.setOnTouchListener(new OnTouchListener() {


            @Override // 触摸时该方法调用。
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                int action = event.getAction();
                switch (action) {
                //用户手指触摸到屏幕
                case MotionEvent.ACTION_DOWN:

                    startx = (int) event.getX();
                    starty = (int) event.getY();

                    break;
                //用户手指抬离屏幕
                case MotionEvent.ACTION_UP:
                    System.out.println("手指离开屏幕");

                    break;
                    //用户手指正在滑动。
                case MotionEvent.ACTION_MOVE:
                    int x = (int) event.getX();
                    int y = (int) event.getY();
                    canvas.drawLine(startx, starty, x, y, paint);
                    //每次画完线后的结束坐标作为下一次的开始坐标。
                    startx= x;
                    starty=y;
                    iv.setImageBitmap(bmcopy); //画完图片后需要显示将图片从新甚至下显示位图。
                    break;


                }
                // 这个触摸侦听事件由该组件自己处理。

                return true;
            }

        });
    }
}

设置画笔的颜色:

//设置画笔的颜色为绿色。
 paint.setColor(Color.GREEN);

可以设置画笔的宽度:
stroke ;画笔、

paint.setStrokeWidth(8); //设置画笔的宽度为8px像素。

画好图片的保存:
保存到内存卡上需要permisson:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    public void save(View v){
        //文件的保存。
        File file =new File("sdcard/dazuo.jpg");  存放文件的地址。
        try {
            fos = new FileOutputStream(file);   //通过文件输出输出流传输。
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        bmcopy.compress(CompressFormat.JPEG, 100, fos);   //第一个是格式format 压缩format定义的
    }

保存图片 发送一广播。sd卡以就绪。
* SD每次准备的时候,系统其实是遍历sd卡所有文件,系统会把所有的多媒体文件,都在MediaStore数据库中生成一个索引,数据库中保存了文件的文件名、路径、大小、长度和艺术家
* 图库、音乐、视频程序每次启动时,其实不会去遍历sd卡寻找多媒体文件,而是直接从MediaStore数据库中读取多媒体文件,通过库中的索引找到对应的多媒体文件后,把文件显示在界面
得到外部的存储文件方法:
Environment.getExternalStorageDirectory()

//发送sd卡就绪广播是为了图库能加载显示该图片。
Intent intent = new Intent();
        intent.setAction(Intent.ACTION_MEDIA_MOUNTED);  //设置action 说明sd卡已准备就绪。
        intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory())); //里面内置了一个file开头。 符合data中的scheme:file
        sendBroadcast(intent);

使触摸经过的地方变成透明色的方法:

int x= (int) event.getX();
int y = (int) event.getY();
bmcopy.setPixel(x, y, Color.TRANSPARENT);   //使触摸经过的地方颜色变成透明色。  设置副本图片的像素。

设置屏幕的触摸监听需要注意:
在组件的外面down然后move不会触发触摸监听的。
组件的上面down然后超过组件范围仍然会触发触摸监听。


音乐:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值