图像处理-矩阵变换
来源:互联网 发布:xml与json的区别是什么 编辑:程序博客网 时间:2024/05/17 01:58
Android中通过矩阵来处理图像问题是非常常见的。
图像中的每一个像素点都是一个颜色矩阵分量,然后我们让这两个矩阵相乘就能得到一个新的矩阵(新的颜色矩阵分量),这就是矩阵变换对图像中的每一个点的处理,使得对整个图像进行处理。通常我们会用下面整个矩阵作为初始矩阵,因为这个矩阵乘以任何矩阵都是不会改变颜色矩阵分量的。
我们对颜色矩阵的分析就可以看出来最后一列不会和原有的RGBA中任何一个有关联,所以我们可以称之为颜色偏移量,通过常数来改变颜色。
然后我们怎么在Android中对图像进行处理的呢,我们就需要新建两个方法,其中一个是获得颜色矩阵的值,还有一个是把颜色矩阵对图像进行处理。其实说白了上面那个调节就是自动生成了一个ColorMatrix(可以通过源码看出来,我就不详细说了),然而现在这种是自己输入ColorMatrix,这就是两种的区别了。
private void getMatrix(){ for(int i=0;i<20;i++){ mColorMatrix[i]=Float.valueOf(mEts[i].getText().toString()); }}private void setImageMatrix(){ Bitmap bmp=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.ARGB_8888);//一定要新建一个Bitmap,因为传进来的Bitmap是不能修改的,需要重新进行绘制 android.graphics.ColorMatrix colorMatrix = new android.graphics.ColorMatrix(); colorMatrix.set(mColorMatrix);//将颜色矩阵放入ColorMatrix中去 Canvas canvas = new Canvas(bmp); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//抗锯齿 paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); canvas.drawBitmap(bitmap,0,0,paint); mImageView.setImageBitmap(bmp);}
下面来个例子:
先编写一个color_matrix.xml的布局文件,有一个ImageView显示图像,然后有一个GridLayout对矩阵进行显示以及修改,然后有三个Button分别对图像进行改变,重置以及选择图片。
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/imageview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" /> <GridLayout android:id="@+id/group" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" android:columnCount="5" android:rowCount="4"> </GridLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/btnChange" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Change" /> <Button android:id="@+id/btnReset" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Reset" /> <Button android:id="@+id/btnChangeImage" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="ChangeImage" /> </LinearLayout></LinearLayout>
然后新建一个ColorMatrix.java文件里面通过我们上述的代码构建出一个ColorMatrix,然后通过这个ColorMatrix重新绘制一个Bitmap显示出来,把上面理解了的话就会好理解好多,Change就是我们根据所调整过后的矩阵对图像进行的处理,Reset就是把矩阵调整成我们上面所说的初始化矩阵,然后在根据这个矩阵对图像进行的处理。其他的就没有什么好说的了,感觉都还蛮容易懂的。
package com.xjh.gin.image;import android.Manifest;import android.content.Intent;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.ColorMatrixColorFilter;import android.graphics.Paint;import android.net.Uri;import android.os.Bundle;import android.provider.MediaStore;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.GridLayout;import android.widget.ImageView;/** * Created by Gin on 2017/11/26. */public class ColorMatrix extends BaseActivity implements View.OnClickListener { private static final int PICK_CODE = 0X110; private ImageView mImageView; private GridLayout mGroup; private String mCurreatPhotoStr; private Bitmap bitmap;//就是单独的bitmap,之后的修改不会覆盖这个Bitmap private Button btn_Change, btn_Reset, btn_ChangeImage; private int mEtWidth, mEtHeight; private EditText[] mEts = new EditText[20]; private float[] mColorMatrix = new float[20]; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.color_matrix); isPermissionAllGranted(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1); initView(); initEvent(); } private void initView() { mImageView = (ImageView) findViewById(R.id.imageview); mGroup = (GridLayout) findViewById(R.id.group); btn_Change = (Button) findViewById(R.id.btnChange); btn_Reset = (Button) findViewById(R.id.btnReset); btn_ChangeImage = (Button) findViewById(R.id.btnChangeImage); } private void initEvent() { btn_Change.setOnClickListener(this); btn_Reset.setOnClickListener(this); btn_ChangeImage.setOnClickListener(this); bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test1); mImageView.setImageBitmap(bitmap); mGroup.post(new Runnable() {//在onCreate方法中因为控件还没有绘制完毕,所以我们无法获得控件的高和宽,所以当控件绘制完毕以后,我们就在线程中获取,因为这时候控件一定绘制完毕了 @Override public void run() { mEtWidth = mGroup.getWidth() / 5; mEtHeight = mGroup.getHeight() / 4; addEts(); initMatrix(); } }); } private void addEts() {//添加EditText for (int i = 0; i < 20; i++) { EditText editText = new EditText(ColorMatrix.this); mEts[i] = editText; mGroup.addView(editText, mEtWidth, mEtHeight);//让editText动态的加载进mGroup中去 } } private void initMatrix() { for (int i = 0; i < 20; i++) { if (i % 6 == 0) { mEts[i].setText(String.valueOf(1)); } else { mEts[i].setText(String.valueOf(0)); } } } private void getMatrix(){ for(int i=0;i<20;i++){ mColorMatrix[i]=Float.valueOf(mEts[i].getText().toString()); } } private void setImageMatrix(){ Bitmap bmp=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.ARGB_8888);//一定要新建一个Bitmap,因为传进来的Bitmap是不能修改的,需要重新进行绘制 android.graphics.ColorMatrix colorMatrix = new android.graphics.ColorMatrix(); colorMatrix.set(mColorMatrix);//将颜色矩阵放入ColorMatrix中去 Canvas canvas = new Canvas(bmp); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//抗锯齿 paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); canvas.drawBitmap(bitmap,0,0,paint); mImageView.setImageBitmap(bmp); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnChange: getMatrix(); setImageMatrix(); break; case R.id.btnReset: initMatrix(); getMatrix(); setImageMatrix(); break; case R.id.btnChangeImage: Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, PICK_CODE); break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PICK_CODE) { if (data != null) { Uri uri = data.getData(); Cursor cursor = getContentResolver().query(uri, null, null, null, null); cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); mCurreatPhotoStr = cursor.getString(idx); cursor.close(); resizePhoto(); } } super.onActivityResult(requestCode, resultCode, data); } private void resizePhoto() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true;//true为不加载图片,只有宽高这类的数据 BitmapFactory.decodeFile(mCurreatPhotoStr, options); double ratio = Math.max(options.outWidth * 1.0d / 1024f, options.outHeight * 1.0d / 1024f);//求出压缩比例 options.inSampleSize = (int) Math.ceil(ratio);//把压缩比例传入options中 options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(mCurreatPhotoStr, options); mImageView.setImageBitmap(bitmap);//压缩图片,mPhoto是压缩过后的Bitmap }}
然后我们就可以发现图像处理其实就是研究不同的颜色矩阵对图像的处理效果
项目GitHub地址:传送门
- 图像处理-矩阵变换
- Android 图像处理-- 矩阵变换
- Delphi图像处理 -- 颜色矩阵变换
- C++图像处理 -- 颜色矩阵变换
- 图像处理之矩阵变换Matrix,ColorMatrix
- 图像处理的坐标变换必备的矩阵知识
- 【图像处理】图像几何变换基础(非弹性变换下如何计算旋转矩阵)
- 【图像处理】直方图变换
- 【图像处理】空间变换
- 图像处理-Gamma变换
- 图像处理傅立叶变换
- 图像处理--颜色变换
- Android图像处理(三)通过矩阵变换实现图像变形特效
- 图像处理---关于像素坐标矩阵变换(平移,旋转,缩放,错切)
- 图像处理---关于像素坐标矩阵变换(平移,旋转,缩放,错切)
- 图像处理中常见变换
- 傅立叶变换与图像处理
- 用DFT变换处理图像
- 机器学习应该准备哪些数学预备知识?
- 【数据库】6数据备份还原,日志,性能优化
- 盘点记录自己学习过程中的难点,跳过的知识点
- java程序员的大数据之路(11):MapReduce的连接
- 使用python下载NCDC数据
- 图像处理-矩阵变换
- 关键字final在java中的运用
- 557. Reverse Words in a String III
- HBase随笔记录权限控制、命名空间、流量限制和表负载均衡
- LDP会话状态机
- 教您用SSH隧道实现远程连接
- JSP中转发和重定向的区别?
- 依次以十进制、八进制和十六进制形式输入三个整数,输出每个整数的十进制、八进制和十六进制形式。 输入输出示例
- 《数据可视化与数据挖掘——基于Tableau和SPSS Modeler图形界面》之连接PDF文件