7.多媒体☞图像图形拍照

来源:互联网 发布:method(i,2))用法Java 编辑:程序博客网 时间:2024/04/30 08:24
%title multi-meida
%toc
 
图片, 音频, 视频, 摄像头
 
= 图片 =
== 加载大图片到内存 ==
我们创建虚拟机时, 默认给每个应用分配的内存大小是16Mb, (VM Heap 16Mb).
如果我们加载大图片时, 很可能导致内存溢出.
 
但是我们会发现, 即使加载的图片只有2-3Mb, 也会溢出, 这是为什么?
位图图像加载到内存中时, 是采用数组来存放数据的. 一个图片其本身可能不是很大,
但是在内存中想要表示这张图片, 需要一个二维数组, 数组大小为图片宽X高(像素数),
这还没完, 一个数组元素大小要包含RGBA四个分量, 即4byte, 这样一乘, 就很大了.
 
如果我们想要加载大图片, 就要进行缩放, 需要下面几步:
# 获取屏幕的宽高
# 获取图片的宽高
# 获取水平缩放比例和垂直缩放比例
# 使用二者中较大的值对图片进行缩放
代码如下:
{{{class="brush:java"
public class MainActivity extends Activity {
    private ImageView iv;
    private int windowWidth ;
    private int windowHeight ;
    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.iv);
        //1. 获取手机屏幕的分辨率 宽高
        Display  display =   getWindowManager().getDefaultDisplay();
        // 下面的方法虽然过时了, 但是还是很经常用
        windowWidth = display.getWidth();
        windowHeight = display.getHeight();
        // Point p = new Point();
        // display.getSize(p);
        // p.x; p.y;
        System.out.println("窗体的宽度:"+windowWidth);
        System.out.println("窗体的高度:"+windowHeight);
    }
 
    public void click(View view){
        // 创建解析器选项
        Options opts =  new Options();
        // 设置解析器 不去真正的解析这个位图  而是解析这个图片的out输出信息,(宽度 高度)
        // 不会为图片的每个点 申请内存空间
        opts.inJustDecodeBounds = true;   
        BitmapFactory.decodeFile("/sdcard/IMG_0017.JPG", opts);
        // 得到图像的宽高
        int picHeight = opts.outHeight;
        int picWidth = opts.outWidth;
        int scaleX = picWidth / windowWidth;
        int scaleY = picHeight / windowHeight;
 
        int scale = 1;
        if(scaleX>scaleY &&  scaleY >1){
            //按照水平缩放
            scale = scaleX;
        }
         if(scaleY>scaleX &&  scaleX >1){
            //按照竖直平缩放
             scale = scaleY;
        }
         // 真正的解析这个位图
         opts.inJustDecodeBounds = false;
         // 设置缩放比例
         opts.inSampleSize = scale;
        Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/IMG_0017.JPG",opts);
        iv.setImageBitmap(bitmap);
    }
}
}}}
 
== 图像的exif信息 ==
            ExifInterface exif = new ExifInterface("/sdcard/IMG_0017.JPG");
            System.out.println(exif.getAttribute(ExifInterface.TAG_DATETIME));
 
 
== 从图库选择图片 ==
这个比较简单, 我们只需要开启系统图库应用的activity, 让其返回数据即可.
{{{class="brush:java"
public class MainActivity extends Activity {
    private ImageView iv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.iv);
    }
    public void click(View view){
        Intent intent = new Intent();
        intent.setAction("android.intent.action.PICK");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.setType("image/*");
        startActivityForResult(intent, 0);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(data!=null){
            Uri uri = data.getData();
            try {
                // 所有uri相关的操作都可以交给 ContentResolver
                InputStream is = getContentResolver().openInputStream(uri);
                Options opts = new Options();
                opts.inSampleSize = 8;
                Bitmap bitmap = BitmapFactory.decodeStream(is, new Rect(), opts);
                iv.setImageBitmap(bitmap);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}
}}}
 
 
== 创建图像的内存拷贝 ==
在应用中, 我们经常会需要对一个图片进行处理, 如旋转, 缩放, 平移等等,
我们不能拿着一个图片的原图进行处理, 而是要创建一个原图的拷贝, 对这个拷贝的图像
进行处理. 下面的代码演示了如何创建图像的内存拷贝
{{{class="brush:java"
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (data != null) {
            Uri uri = data.getData();
            iv_src.setImageURI(uri);
            try {
                InputStream is = getContentResolver().openInputStream(uri);
                //创建一个原图的拷贝, 把拷贝的图片 放在iv_dest
                //原图对应的bitmap  注意:这个图片是只读的 不可以被修改.
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                //创建一个可以被修改的位图资源,宽高信息 和 图片的类型 跟原图是一模一样
                //下面的代码创建的图片 是一个空白的图片
                Bitmap  alterBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
                // 拿着可以被修改的图片创建一个画布, 之后画的东西就要画在这块画布上了.
                Canvas canvas = new Canvas(alterBitmap);
                // 创建一个画笔, 可以拿着它画东西
                Paint paint = new Paint();
                //创建图形的拷贝, 其实就是把原图按照 Matrix 定义的信息滑到之前的画布上.
                canvas.drawBitmap(bitmap, new Matrix(), paint);
                // 再往上面写点字
                paint.setColor(Color.BLACK);
                canvas.drawText("美女", 10, 10, paint);
                iv_dest.setImageBitmap(alterBitmap);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}
}}}
 
== 图像的简单处理 ==
有了图像的内存拷贝, 我们就可以方便的对图像进行处理了.
1. 缩放
{{{class="brush:java"
// 创建一个bitmap, 作为可以修改的图像, 为什么这里要搞成这个大小?
// 这将是我们创建的画布的大小, 无论图像怎么缩放, 画布就是这么大
Bitmap  alterBitmap = Bitmap.createBitmap(bitmap.getWidth()/2,
    (int)(bitmap.getHeight()*1.2), bitmap.getConfig());
//拿着可以被修改的图片创建一个画布.
Canvas canvas = new Canvas(alterBitmap);
Paint paint = new Paint();
// Matrix 是一个坐标矩阵, 可以用来指定图像每个点的坐标计算方式
// matrix有一个计算公式, 参看图形学ppt
Matrix matrix = new Matrix();
// 这些参数是 X, Y , Z 轴
/*matrix.setValues(new float[] {
    0.5f, 0, 0,
    0, 1.2f, 0,
    0, 0, 1
});*/
// 简单的方法设置缩放量, x轴, y轴
matrix.setScale(0.5f, 1.2f);
// 把原图按照设定好的 matrix 画到画布上
canvas.drawBitmap(bitmap, matrix, paint);
}}}
 
2. 旋转
{{{class="brush:java"
// 为什么宽度要加60? 旋转后图片可能超出原来的范围了, 所以要加宽一点.
Bitmap  alterBitmap = Bitmap.createBitmap(bitmap.getWidth()+60, bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(alterBitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
Matrix matrix = new Matrix();
// 第一个参数指定旋转角度, 后面两个参数指定旋转中心
matrix.setRotate(30, bitmap.getWidth()/2, bitmap.getHeight()/2);
canvas.drawBitmap(bitmap, matrix, paint);
}}}
 
3. 平移
{{{class="brush:java"
Bitmap  alterBitmap = Bitmap.createBitmap(bitmap.getWidth()+60, bitmap.getHeight(), bitmap.getConfig());   
Canvas canvas = new Canvas(alterBitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
Matrix matrix = new Matrix();
// 设置偏移量, 第一个为x轴, 第二个为y轴
matrix.postTranslate(20, 0);
canvas.drawBitmap(bitmap, matrix, paint);
}}}
 
4. 镜面
{{{class="brush:java"
Bitmap  alterBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(alterBitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
Matrix matrix = new Matrix();
// 如果想让x轴变为负的, 第一个参数给-1, 算是缩放的另一种形式吧
matrix.setScale(-1, 1);
// x轴变成负的后, 还要在平移回来, 要不就看不见了.
matrix.postTranslate(bitmap.getWidth(),0);
canvas.drawBitmap(bitmap, matrix, paint);
}}}
 
5. 倒影
{{{class="brush:java"
Bitmap  alterBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(alterBitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
Matrix matrix = new Matrix();
// y轴变成负的即可
matrix.setScale(1, -1);
matrix.postTranslate(0,bitmap.getHeight());
canvas.drawBitmap(bitmap, matrix, paint);
}}}
 
谷歌: www.google.ie or www.google.fr
搜索: 图像处理 filetype:ppt
 
== 扒掉美女的衣服 ==
 
 
== 处理图片的颜色 ==
图像的位移, 旋转等需要的是 坐标矩阵, 修改图像的颜色则需要修改图片的颜色矩阵.
{{{class="brush:java"
alterBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
canvas = new Canvas(alterBitmap);
paint = new Paint();
paint.setAntiAlias(true);
Matrix matrix = new Matrix();
// 创建一个颜色矩阵, 这些参数为 R, G, B, A
ColorMatrix cm = new ColorMatrix();
// 把红色调成两倍
cm.set(new float[] {
2, 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(bitmap, matrix, paint);
}}}
 
== 图片合成/人脸识别 ==
 
face++
 
 
-------------------------------
 
SeekBar 是 ProgressBar 的子类
-------------
自己写个音乐播放器
 
多线程断线下载, 重写一遍
-------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


来自为知笔记(Wiz)


0 0
原创粉丝点击