前一篇文章讲述了Android拍照、截图、保存并显示在ImageView控件中,该篇文章继续讲述Android图像处理技术,主要操作包含:通过打开相冊里的图片,使用Matrix对图像进行缩放、旋转、移动、对照度、亮度、饱和度操作,希望对大家有所帮助.

一. 显示打开图片

   
首先,设置activity_main.xml布局例如以下所看到的:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.example.cangeimagetest.MainActivity"
tools:ignore="MergeRootFrame" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="选择图片" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
android:text="原图显示" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
android:text="变化后的图片" />
<ImageView
android:id="@+id/imageView2"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true" >
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="缩小" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="放大" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="旋转" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="饱和" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="对照" />
</LinearLayout>
</RelativeLayout>

   
然后,在Mainctivity.java中public class MainActivity extends Activity函数加入代码例如以下:

private Button selectBn;
private ImageView imageShow;
private ImageView imageCreate;
private TextView textview1;
private TextView textview2;
private Bitmap bmp; //原始图片 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
selectBn = (Button) findViewById(R.id.button1);
imageShow = (ImageView) findViewById(R.id.imageView1);
imageCreate = (ImageView) findViewById(R.id.imageView2);
textview1 = (TextView) findViewById(R.id.textView1);
textview2 = (TextView) findViewById(R.id.textView2); //选择图片
selectBn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0 );
}
});
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
//显示两张图片
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==RESULT_OK) {
ShowPhotoByImageView(data); //显示照片
CreatePhotoByImageView(); //创建图片
}
}

   
再调用自己定义函数实现显示图片:

//自己定义函数 显示打开的照片在ImageView1中
public void ShowPhotoByImageView(Intent data) {
Uri imageFileUri = data.getData();
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels; //手机屏幕水平分辨率
int height = dm.heightPixels; //手机屏幕垂直分辨率
Log.v("height", ""+height );
Log.v("width", ""+width);
try {
// Load up the image's dimensions not the image itself
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
Log.v("bmpheight", ""+bmpFactoryOptions.outHeight);
Log.v("bmpheight", ""+bmpFactoryOptions.outWidth);
if(heightRatio>1&&widthRatio>1) {
if(heightRatio>widthRatio) {
bmpFactoryOptions.inSampleSize = heightRatio*2;
}
else {
bmpFactoryOptions.inSampleSize = widthRatio*2;
}
}
//图像真正解码
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);
imageShow.setImageBitmap(bmp); //将剪裁后照片显示出来
textview1.setVisibility(View.VISIBLE);
} catch(FileNotFoundException e) {
e.printStackTrace();
}
}
//创建第二张图片并显示
public void CreatePhotoByImageView() {
try {
Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(createBmp); //画布 传入位图用于绘制
Paint paint = new Paint(); //画刷 改变颜色 对照度等属性
canvas.drawBitmap(bmp, 0, 0, paint); //错误:没有图片 由于參数bmp写成createBmp
imageCreate.setImageBitmap(createBmp);
textview2.setVisibility(View.VISIBLE);
} catch(Exception e) {
e.printStackTrace();
}
}

   
显示的效果例如以下图所看到的,该图叫莱娜图(Lenna),是图像处理中常常使用的例子图.

二. Matrix操作

   然后通过Matrix对图像进行处理操作,在onCreate函数中加入点击事件:

//缩小图片
Button button2=(Button)findViewById(R.id.button2);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SmallPicture();
}
});
//放大图片
Button button3=(Button)findViewById(R.id.button3);
button3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
BigPicture();
}
});
//旋转图片
Button button4=(Button)findViewById(R.id.button4);
button4.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TurnPicture();
}
});
//图片饱和度改变
Button button5=(Button)findViewById(R.id.button5);
button5.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SaturationPicture();
}
});
//图片对照度改变
Button button6=(Button)findViewById(R.id.button6);
button6.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ContrastPicture();
}
});

   
最后分别自己定义函数各操作实现,代码例如以下:

//缩小图片
private void SmallPicture() {
Matrix matrix = new Matrix();
//缩放区间 0.5-1.0
if(smallbig>0.5f)
smallbig=smallbig-0.1f;
else
smallbig=0.5f;
//x y坐标同一时候缩放
matrix.setScale(smallbig,smallbig,bmp.getWidth()/2,bmp.getHeight()/2);
Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(createBmp); //画布 传入位图用于绘制
Paint paint = new Paint(); //画刷 改变颜色 对照度等属性
canvas.drawBitmap(bmp, matrix, paint);
imageCreate.setBackgroundColor(Color.RED);
imageCreate.setImageBitmap(createBmp);
textview2.setVisibility(View.VISIBLE);
}
//放大图片
private void BigPicture() {
Matrix matrix = new Matrix();
//缩放区间 0.5-1.0
if(smallbig<1.5f)
smallbig=smallbig+0.1f;
else
smallbig=1.5f;
//x y坐标同一时候缩放
matrix.setScale(smallbig,smallbig,bmp.getWidth()/2,bmp.getHeight()/2);
Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(createBmp);
Paint paint = new Paint();
canvas.drawBitmap(bmp, matrix, paint);
imageCreate.setBackgroundColor(Color.RED);
imageCreate.setImageBitmap(createBmp);
textview2.setVisibility(View.VISIBLE);
}
//旋转图片
private void TurnPicture() {
Matrix matrix = new Matrix();
turnRotate=turnRotate+15;
//选择角度 饶(0,0)点选择 正数顺时针 负数逆时针 中心旋转
matrix.setRotate(turnRotate,bmp.getWidth()/2,bmp.getHeight()/2);
Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(createBmp);
Paint paint = new Paint();
canvas.drawBitmap(bmp, matrix, paint);
imageCreate.setBackgroundColor(Color.RED);
imageCreate.setImageBitmap(createBmp);
textview2.setVisibility(View.VISIBLE);
}
//改变图像饱和度
private void SaturationPicture() {
//设置饱和度 0表示灰度图像 大于1饱和度添加 0-1饱和度减小
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(saturation);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cm));
//显示图片
Matrix matrix = new Matrix();
Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(createBmp);
canvas.drawBitmap(bmp, matrix, paint);
imageCreate.setImageBitmap(createBmp);
textview2.setVisibility(View.VISIBLE);
saturation=saturation+0.1f;
if(saturation>=1.5f) {
saturation=0f;
}
}
//设置图片对照度
private void ContrastPicture() {
ColorMatrix cm = new ColorMatrix();
float brightness = -25; //亮度
float contrast = 2; //对照度
cm.set(new float[] {
contrast, 0, 0, 0, brightness,
0, contrast, 0, 0, brightness,
0, 0, contrast, 0, brightness,
0, 0, 0, contrast, 0
});
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cm));
//显示图片
Matrix matrix = new Matrix();
Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(createBmp);
canvas.drawBitmap(bmp, matrix, paint);
imageCreate.setImageBitmap(createBmp);
textview2.setVisibility(View.VISIBLE);
}

   
同一时候自己定义变量例如以下:

//图片变换參数
private float smallbig=1.0f; //缩放比例
private int turnRotate=0; //旋转度数
private float saturation=0f; //饱和度

   
它的执行结果例如以下图所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRWFzdG1vdW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="240" height="320">   

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRWFzdG1vdW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="240" height="320">

   

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRWFzdG1vdW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="240" height="320">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRWFzdG1vdW50/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="240" height="320">   

    须要指出的是:该项目只讲述处理的过程,并没有考虑非常多因素,如:有的图像显示可能超出屏幕,没有加载图片点击处理button报错,横竖屏切换导致不显示图片,最以下button可能被遮挡,图像放大画布没有变,由于为觉得显示一张改变后的图片效果更好,而该project不过对照.图像缩放移动触屏变换更好,下一篇讲述.

    XML布局推荐:http://www.apkbus.com/forum.php?mod=viewthread&tid=44949

    解决画布跟着图片放大:http://www.eoeandroid.com/thread-3162-1-1.html

三. Matrix处理的原理

   
Android中能够通过Matrix和ColorMatrix对图像进行处理.

    1.Matrix

    图像空间变换,包含旋转、剪裁、缩放或移动.Matrix类中每一个数字都将应用于图像上每一个点的3个坐标x\y\z之中的一个.

    例如以下代码通过setValues设置值.(1,0,0)表示x坐标转换x=1x+0y+0z,相同y=0x+1y+0z,z=0x+0y+1z.该矩阵不做不论什么变换.假设第一行改为(.5f,0,0),那么图像在x轴上将图像压缩50%.移动见setTranslate()函数.

Matrix matrix = new Matrix();
matrix.setValues(new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1
});

    2.ColorMatrix

    在Canvas(画布)对象上绘制时既可使用Matrix方法,也可使用ColorMatrix来改变在Canvas对象上绘制的Paint(画刷)对象.对图像的像素处理时,每一个像素由RGBA值组成(Red Green Blue Alpha).详细方法推荐博文:http://www.cnblogs.com/leon19870907/articles/1978065.html

    最后希望该文章对大家有所帮助,尤其是Android刚開始学习的人.该文章是讲述Android使用Matrix处理图片的基础文章,假设有不足或错误地方,请见谅~參考资料《Android多媒体开发高级编程 著:Shawn Van Every

    下载地址:http://download.csdn.net/detail/eastmount/8082043

(By:Eastmount 2014-10-26 夜2点 http://blog.csdn.net/eastmount)

[Android] 使用Matrix矩阵类对图像进行缩放、旋转、对照度、亮度处理的更多相关文章

  1. [Java]编写自己的Matrix矩阵类

    用java实现一个简单的矩阵类,可以实现简单的矩阵计算功能. class Matrix 1.向量点乘 public static double dot(double[] x,double[] y) 2 ...

  2. WPF 触摸屏多点触控图像的缩放旋转和移动

    <dxc:DXWindow xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" xmlns:d ...

  3. 矩阵类的python实现

    科学计算离不开矩阵的运算.当然,python已经有非常好的现成的库:numpy. 我写这个矩阵类,并不是打算重新造一个轮子,只是作为一个练习,记录在此. 注:这个类的函数还没全部实现,慢慢在完善吧. ...

  4. C++实现矩阵类和向量类

    C++期末作业内容,写完之后觉得过于臃肿,又重新搞了个新的.新的当作业交,旧的拿来给同学参考. [问题描述]请仿照复数类,设计一个矩阵类,设计矩阵类的构成元素 1.编写构造函数完成初始化 2.编写成员 ...

  5. Android中的Matrix(矩阵)

    写在前面 看这篇笔记之前先看一下参考文章,这篇笔记没有系统的讲述矩阵和代码的东西,参考文章写的也有错误的地方,要辨证的看. 如何计算矩阵乘法 android matrix 最全方法详解与进阶(完整篇) ...

  6. Android图像格式类及图像转换方法

    Android图像格式类及图像转换方法介绍 一款软件的开发和图像密切相关,特别是移动应用程序,在视觉效果等方面是至关重要的,因为这直接关系到用户的体验效果.在Android程序开发的过程中,了解存在哪 ...

  7. Android学习笔记进阶八之Matrix矩阵

    Matrix,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放.平移.旋转等操作. 在Android里面,Matrix由9个float值构成,是一个3*3的矩阵.最好记住.如下图: ...

  8. Android笔记——Matrix

    转自:http://www.cnblogs.com/qiengo/archive/2012/06/30/2570874.html#translate Matrix的数学原理 在Android中,如果你 ...

  9. (转)android中颜色矩阵colormatrix

    原文地址:http://www.cnblogs.com/menlsh/archive/2013/02/03/2890888.html 在Android中,对图像进行颜色方面的处理,如黑白老照片.泛黄旧 ...

随机推荐

  1. MyBatis学习总结(7)——Mybatis缓存

    一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Se ...

  2. CF16A Flag

    CF16A Flag 题意翻译 题目描述 根据一项新的ISO标准,每一个国家的国旗应该是一个n×m的格子场,其中每个格子最多有10种不同的颜色.并且国旗应该有条纹:旗帜的每一行应包含相同颜色的方块,相 ...

  3. sql学习笔记(18)-----------数据库创建过程

    手动创建数据库的步骤:   第一步:决定数据库实例的SID 数据库实例的SID用来将当前实例和以后可能创建的实例进行区分 % setenv ORACLE_SID mynewdb     第二步:建立数 ...

  4. 浅谈SaaS应用开发的难度

    近期做SaaS应用的非常多,这样的模式是未来的一种趋势,这样的模式的最大优点就是云计算的优点--节约资源.网上有非常多人觉得SaaS非常easy,就是一个多用户租赁模式.这样的认识也不能说不正确.由于 ...

  5. linux 数据库

    查看数据库状态:service mysqld status 启动数据库服务 service mysql start 如果出现:Another MySQL daemon already running ...

  6. bzoj2756: [SCOI2012]奇怪的游戏(网络流+分情况)

    2756: [SCOI2012]奇怪的游戏 题目:传送门 题解: 发现做不出来的大难题一点一个网络流 %大佬 首先黑白染色(原来是套路...)染色之后就可以保证每次操作都一定会使黑白各一个各自的值加1 ...

  7. 不仅仅是Google,您必须知道的全球十大地图API

    不仅仅是Google,您必须知道的全球十大地图API 一.总结 一句话总结:除了google,也有其它很多很好的地图,必应地图(Bing Maps),OpenLayers 二.不仅仅是Google,您 ...

  8. tensorflow入门教程和底层机制简单解说——本质就是图计算,自动寻找依赖,想想spark机制就明白了

    简介 本章的目的是让你了解和运行 TensorFlow! 在开始之前, 让我们先看一段使用 Python API 撰写的 TensorFlow 示例代码, 让你对将要学习的内容有初步的印象. 这段很短 ...

  9. [JZOJ 5908] [NOIP2018模拟10.16] 开荒(kaihuang)解题报告 (树状数组+思维)

    题目链接: https://jzoj.net/senior/#contest/show/2529/1 题目: 题目背景:尊者神高达作为一个萌新,在升级路上死亡无数次后被一只大黄叽带回了师门.他加入师门 ...

  10. hexo博客谷歌百度收录踩坑日记

    title: hexo博客谷歌百度收录踩坑日记 toc: false date: 2018-04-17 00:09:38 百度收录文件验证 无论怎么把渲染关掉或者render_skip都说我的格式错误 ...