位置: 编程技术 - 正文

木瓜妮子多媒体开发教程---第二天---Android下对图像的几何操作(请问木瓜)

编辑:rootadmin
几何操作 ---- 图像的基本操作完成对图像的基本操作:

推荐整理分享木瓜妮子多媒体开发教程---第二天---Android下对图像的几何操作(请问木瓜),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:木瓜整装,木瓜官方,木瓜官方,木瓜官方,木瓜电子,木瓜木本,木瓜木本,木瓜妮子多媒体app,内容如对您有帮助,希望把文章链接给更多的朋友!

1、打开一张图片并将图片显示在界面上。

2、采用进度条控制图片的缩放,旋转,亮度和对比度调节。

那么比较重要的技术点在于:

1、掌握从图库中返回图像的操作,学会将图放置在ImageView控件上,学会使用画笔、画布类作图。

2、掌握setScale、setRotate的使用,熟悉亮度和对比度系数矩阵。

3、了解Intent显式的启动相册Activity的操作,并与原Activity进行通信。

Android提供了API文档,查阅文档得到类中方法的接口和demo。

本教程所使用的主要类包括:

android.graphics.Bitmap;

android.graphics.BitmapFactory;

android.graphics.Canvas;

android.graphics.ColorMatrix;

android.graphics.ColorMatrixColorFilter;

android.graphics.Matrix;

android.graphics.Paint;

android.widget.SeekBar;

android.widget.SeekBar.OnSeekBarChangeListener;

1.Android如何获得图像资源?

Android获得图像资源有三种常用的方法:

1.图片放在sdcard中,Bitmap imageBitmap = BitmapFactory.decodeFile(path) ,其中path 是图片的绝对路径;

2. 图片在项目的res-->drawable文件夹下,Drawabledrawable = getResource().getDrawable(R.drawable.pic);

3. 通过显式意图,从拍照或者图库中返回图像。

public void onClick(View v) {Intent choosephotoIntent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);//打开图库文件startActivityForResult(choosephotoIntent,1);//图库返回结果}

在onActivityResult(requestCode, resultCode, data)方法中添加

Bitmap cameraBitmap = (Bitmap) data.getExtras().get("data");//得到图片

2.图像几何操作:

数字图像的几何变换是计算机图像处理领域的一个重要课题,它使原始图像按照实际需要产生大小、形状或者位置的变化。根据变换的性质,图像的几何变换可分为位置变换(平移、镜像、旋转)、形状变换(缩放、截取、错切)和复合变换等。

在Android API中有一个Matrix(矩阵)类,可以完成对当前位图对象的重新绘制,也可以绘制一个全新的位图对象。在进行图像的空间的几何变换时可以选择使用该类,完成对图像的旋转、裁剪、缩放或是更改图像的坐标空间。Matrix类是有9个数字的数组来表示转换的。数字可以手动输入,也可以通过进度条控制输入。

简单举例:

Matrixmatrixzoom =new Matrix();

matrixzoom.setValues(newfloat[]{

.5f,0,0,

0,1,0,

0,0,1

});

canvas.drawBitmap(bmp,matrixzoom, paint);

通过手动设置缩放矩阵,完成对图像的操作。操作的结果是在x轴上图像被压缩了%,由此可见第一行的.5f影响了x的坐标&#;,使图像被压缩了%。若同时将第二行第二列的1改为.5f,则图像在x轴和y轴方向被同时压缩%,如果改为2,则为扩展一倍。

Matrix matrixzoom =new Matrix();

matrixzoom.setValues(newfloat[]{

1,.5f,0,

0,1,0,

0,0,1

});

canvas.drawBitmap(bmp,matrixzoom, paint);

操作的结果是导致图像的倾斜,因为第一行第二列的.5f使得每个像素的x&#;需要根据像素的y&#;进行改变,即X = X&#;0.5Y,当y&#;增加时,x&#;也会随之增加,空出来的部分用黑色补齐,图片就产生了倾斜的效果。

如果不想通过自己手动修改矩阵来使图片缩放,可以采用下面的内置方法实现:

Matrix matrixzoom =newMatrix();

matrixzoom.setScale(.5f,.5f);

canvas.drawBitmap(bmp,matrixzoom, paint);

此操作的效果是对图片整体进行了%的缩放,其中第一个参数控制X轴,第二个参数控制Y轴。

Matrix matrixrotate =newMatrix();

matrixrotate.setRotate();

canvas.drawBitmap(bmp,matrixrotate, paint);

操作的结果是图像产生了度的顺时针旋转,如果设置为负数则会逆时针旋转图像,旋转的中心为左上角。

matrixrotate.setRotate(,bmp.getWidth()/2,bmp.getHeight()/2);

操作可以保证图像的中心点是旋转点。

3.图像颜色&#;处理:

类&#;于Matrix对象的使用方法,Android提供了一个ColorMatrix类库,这个类可以改变Paint对象。ColorMatrix也是一个数字数组,不同于操作x、y、z坐标,它操作的是RGB颜色&#;和Alpha&#;。

在ColorMatrix中共包含个浮点数,第一行包含了在单个像素的红色部分上发生的操作,第二行影响了绿色部分,第三行影响蓝色部分,最后一行的操作数可控制像素的Alpha&#;。

float lightness= ;

ColorMatrixmatrixlightness =newColorMatrix();

matrixlightness.set(newfloat[]{//设计亮度矩阵

1,0,0,0,lightness,

0,1,0,0,lightness,

0,0,1,0,lightness,

0,0,0,1,0

木瓜妮子多媒体开发教程---第二天---Android下对图像的几何操作(请问木瓜)

});

paint.setColorFilter(newColorMatrixColorFilter(matrixlightness));

Matrixmatrix_lightness =newMatrix();

canvas.drawBitmap(bmp,matrix_lightness, paint);

此操作的结果是可提升图片亮度。

float contrast = 3;

ColorMatrixmatrixcontrast =newColorMatrix();

matrixcontrast.set(newfloat[]{//对比度矩阵

contrast,0,0,0,0,

0,contrast,0,0,0,

0,0,contrast,0,0,

0,0,0,1,0

});

paint.setColorFilter(newColorMatrixColorFilter(matrixcontrast));

Matrixmatrix_contrast =newMatrix();

canvas.drawBitmap(bmp,matrix_contrast, paint);

此操作的结果是提升了图片的对比度。

4.SeekBar设计:

通常我们采用进度条seekbar来控制一个控件的进度。在这里,我们可以用来控制缩放倍数、旋转角度和亮度、对比度的&#;。

<SeekBar

android:id="@&#;id/seekBar1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignLeft="@&#;id/seekBar2"

android:max=""

android:progress=""/>

默认seekbar的最大&#;为,Android:max可以重新设定最大&#;,Android:progress可以设定当前&#;。

seekbar1.setOnSeekBarChangeListener(newOnSeekBarChangeListener() {

publicvoidonProgressChanged(SeekBar arg0, intarg1, boolean arg2) {

float zoom= (float) arg1 / ;

Matrixmatrixzoom =new Matrix();

matrixzoom.setScale(zoom,zoom);//通过构建缩放矩阵完成功能

canvas.drawBitmap(bitmap,matrixzoom, paint); }

public voidonStartTrackingTouch(SeekBar arg0) {

}

public voidonStopTrackingTouch(SeekBar arg0) {

}

在Mainactivity中对seekbar进行动作设置。为Seekbar设置一个侦听器,当进度条被拖动时,即执行onProgressChanged方法。对onProgressChanged方法进行复写,arg1表示当前拖动条进度,赋&#;给zoom变量,用来控制缩放的倍数。

onStartTrackingTouch在按下拖动条瞬间执行,onStopTrackingTouch在松开拖动条的瞬间执行。

如果想要实现亮度和对比度的同时变化,矩阵应该怎样构成呢?

结合了对比度和亮度矩阵,构成方法是这样的,同时调节可以调节图片的多种曝光效果:

matrix.set(newfloat[]{//对比度亮度矩阵

contrast,0,0,0,lightness,

0,contrast,0,0,lightness,

0,0,contrast,0,lightness,

0,0,0,1,0

});

----------------------讲解的部分就到这里,下面开始要发干货了,小伙伴们准备接招!----------------------------

MainActivity.java部分

//功能:实现对原图的编辑:缩放、旋转、亮度、对比度的调节。public class MainActivity extends Activity {private SeekBar sb1 = null;private SeekBar sb2 = null;private SeekBar sb3 = null;private SeekBar sb4 = null;private Button choosephoto = null;private ImageView originalphoto = null;private ImageView secondphoto = null;private Bitmap bmp = null;private Bitmap bmp1;@Overrideprotected void onCreate(Bundle savedInstanceState) {setContentView(R.layout.activity_main);choosephoto = (Button) this.findViewById(R.id.Bton1);// 得到控件originalphoto = (ImageView) this.findViewById(R.id.ImgView1);secondphoto = (ImageView) this.findViewById(R.id.ImgView2);choosephoto.setOnClickListener(new View.OnClickListener() {// 为“打开图片”按钮设置动作,采用匿名内部类的方式,此方式虽然书写方便但是造成代码混乱。@Overridepublic void onClick(View v) {Intent choosephotoIntent = new Intent(//打开一个显式意图Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);// 打开图库文件startActivityForResult(choosephotoIntent, 1);// 图库返回结果}});}protected void onActivityResult(int requestCode, int resultCode, Intent data) {// 对返回结果的处理:各种对图像的编辑操作super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {Uri imageuri = data.getData();System.out.println("the Uri is " &#; imageuri);Display currentDisplay = getWindowManager().getDefaultDisplay();// 为了能快速加载图片,需要将原图缩放到合适大小,“合适”的标准由宽高wratio和hratio来决定。int dw = currentDisplay.getWidth() / 2 - ;int dh = currentDisplay.getHeight() / 2 - ;System.out.println("the dw is " &#; dw);System.out.println("the dh is " &#; dh);try {BitmapFactory.Options bmpopt = new BitmapFactory.Options();//bmpopt.inJustDecodeBounds = true;System.out.println("bitmap is decode ");bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageuri), null, bmpopt);int hratio = (int) Math.ceil(bmpopt.outHeight / (float) dh);// 率=图片高/屏幕高int wratio = (int) Math.ceil(bmpopt.outWidth / (float) dw);// 率=图片宽/屏幕宽System.out.println("the hratio is " &#; hratio);System.out.println("the wratio is " &#; wratio);if (hratio > 1 && wratio > 1) {// 判断得到合适的缩放比率if (hratio >= wratio) {bmpopt.inSampleSize = hratio;} else {bmpopt.inSampleSize = wratio;}}bmpopt.inJustDecodeBounds = false;bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageuri), null, bmpopt);originalphoto.setImageBitmap(bmp);// 显示经过缩放后的图库原图片bmp1 = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(),bmp.getConfig());// 创建新位图final Canvas canvas = new Canvas(bmp1);// 画布final Paint paint = new Paint();// 画笔paint.setAntiAlias(true);// 消除锯齿canvas.drawBitmap(bmp, 0, 0, paint);secondphoto.setImageBitmap(bmp1);// 显示新位图,初始时和原图一致sb1 = (SeekBar) findViewById(R.id.seekBar1);// 得到四个控制条控件sb2 = (SeekBar) findViewById(R.id.seekBar2);sb3 = (SeekBar) findViewById(R.id.seekBar3);sb4 = (SeekBar) findViewById(R.id.seekBar4);sb1.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {// 设置控制条操作@Overridepublic void onProgressChanged(SeekBar arg0, int arg1,boolean arg2) {float zoom = (float) arg1 / ;Matrix matrixzoom = new Matrix();matrixzoom.setValues(new float[] { .5f, 0, 0, 0, 1, 0,0, 0, 1 });matrixzoom.setScale(zoom, zoom);// 通过构建缩放矩阵完成功能canvas.drawBitmap(bmp, matrixzoom, paint);secondphoto.setImageBitmap(bmp1);}@Overridepublic void onStartTrackingTouch(SeekBar arg0) {}@Overridepublic void onStopTrackingTouch(SeekBar arg0) {}});sb2.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar arg0) {}@Overridepublic void onStartTrackingTouch(SeekBar arg0) {}@Overridepublic void onProgressChanged(SeekBar arg0, int arg1,boolean arg2) {float rotate = (float) arg1 * / ;Matrix matrixrotate = new Matrix();matrixrotate.setRotate(rotate, bmp.getWidth() / 2,bmp.getHeight() / 2);// 设置旋转操作,并约束了宽高canvas.drawBitmap(bmp, matrixrotate, paint);secondphoto.setImageBitmap(bmp1);}});sb3.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar arg0) {}@Overridepublic void onStartTrackingTouch(SeekBar arg0) {}@Overridepublic void onProgressChanged(SeekBar arg0, int arg1,boolean arg2) {float lightness = (arg1 - ) / 3;ColorMatrix matrixlightness = new ColorMatrix();matrixlightness.set(new float[] {// 设计亮度矩阵1, 0, 0, 0, lightness, 0, 1, 0, 0, lightness,0, 0, 1, 0, lightness, 0, 0, 0, 1, 0 });paint.setColorFilter(new ColorMatrixColorFilter(matrixlightness));Matrix matrix_lightness = new Matrix();canvas.drawBitmap(bmp, matrix_lightness, paint);// 很不幸,这里的亮度和对比度只能单独针对原图变化,而不能混合使用。secondphoto.setImageBitmap(bmp1);}});sb4.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar arg0) {}@Overridepublic void onStartTrackingTouch(SeekBar arg0) {}@Overridepublic void onProgressChanged(SeekBar arg0, int arg1,boolean arg2) {float contrast = (float) arg1 / ;ColorMatrix matrixcontrast = new ColorMatrix();matrixcontrast.set(new float[] {// 对比度矩阵contrast, 0, 0, 0, 0, 0, contrast, 0, 0, 0, 0,0, contrast, 0, 0, 0, 0, 0, 1, 0 });paint.setColorFilter(new ColorMatrixColorFilter(matrixcontrast));Matrix matrix_contrast = new Matrix();canvas.drawBitmap(bmp, matrix_contrast, paint);secondphoto.setImageBitmap(bmp1);}});} catch (FileNotFoundException e) {// 捕获异常的操作Log.v("error", e.toString());}}}}

布局文件

<RelativeLayout xmlns:android=" xmlns:tools=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <TextView android:id="@&#;id/textView1" android:layout_width="dp" android:layout_height="wrap_content" android:text="@string/zoom" android:textColor="#" android:textStyle="bold" /> <SeekBar android:id="@&#;id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@&#;id/seekBar2" android:max="" android:progress="" android:secondaryProgress="" /> <TextView android:id="@&#;id/textView2" android:layout_width="dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignTop="@&#;id/seekBar2" android:text="@string/rotate" android:textColor="#" android:textStyle="bold" /> <SeekBar android:id="@&#;id/seekBar2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@&#;id/seekBar1" android:layout_toRightOf="@&#;id/textView2" android:max="" android:progress="" android:secondaryProgress="" /> <TextView android:id="@&#;id/textView3" android:layout_width="dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignTop="@&#;id/seekBar3" android:text="@string/brightness" android:textColor="#" android:textStyle="bold" /> <SeekBar android:id="@&#;id/seekBar3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@&#;id/seekBar2" android:layout_toRightOf="@&#;id/textView3" android:max="" android:progress="" android:secondaryProgress="" /> <TextView android:id="@&#;id/textView4" android:layout_width="dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignTop="@&#;id/seekBar4" android:text="@string/contrast" android:textColor="#" android:textStyle="bold" /> <SeekBar android:id="@&#;id/seekBar4" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@&#;id/seekBar3" android:layout_toRightOf="@&#;id/textView4" android:max="" android:progress="" android:secondaryProgress="" /> <ImageView android:id="@&#;id/ImgView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="dp" android:layout_alignParentLeft="true" android:background="#" /> <ImageView android:id="@&#;id/ImgView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="dp" android:layout_alignParentRight="true" android:background="#eee" /> <Button android:id="@&#;id/Bton1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@&#;id/seekBar4" android:text="@string/bt1" /></RelativeLayout>

Manifest.xml文件中别忘了添加:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

项目完成!

[开源] android apk 一键生成混淆文件 脚本分享 (python) 今天做的项目有个需求。要把我们的apk混淆一下。于是花了一下午的时间研究了一下,用python写了个一键生成的脚本。原理:我的开发环境是adtbundle是an

View分析总结 通过阅读android官方文档,知悉View的相关绘画流程和重要方法,以此为脉络来一一分析View。要分析一个事物,至少对该事物有一定了解,最好能知道该

Android进程间通信--AIDL 本文讲解AIDL的基本使用,通过本文的学习你应该掌握如下内容:1.了解Android进程间通信IPC(interprocessCommunication);2.学会AIDL的基本使用方法,实现在进程间

标签: 请问木瓜

本文链接地址:https://www.jiuchutong.com/biancheng/381052.html 转载请保留说明!

上一篇:在xml文件里使用<fragment>报android.view.InflateException: Error inflating class fragment(在xml文件里使用的命令)

下一篇:[开源] android apk 一键生成混淆文件 脚本分享 (python)(开源 android 播放器)

  • 金税四期税务机关一局式
  • 加班费计入个税吗
  • 员工报销公司是哪个部门
  • 企业放贷利息收多少合适
  • 外资企业撤退
  • 采购是进项还是销项
  • 增值税即征即退2023政策
  • 举办活动的工作要求
  • 员工奖金分两次发怎么交税?
  • 什么是成本核算你觉得成本核算重要吗为什么
  • 核定征收的企业需要做账吗
  • 施工单位的项目
  • 商业承兑汇票贴现转让
  • 固定资产评估费计入什么会计科目
  • 物业公司水费差额征税不备案
  • 付现所得税体现在哪方面
  • 旧税号的发票专用章还能使用吗
  • 收到财政补贴收入贷记科目是
  • 对公收到别人的转账怎么记账
  • 厂区绿化工程计入什么科目
  • thinkphp5框架介绍
  • 月末增值税计算公式
  • 实收资本一定要打进公司对公户吗
  • php简单聊天室源码
  • 怎样搭建php开发平台
  • 实际收到的货款怎么做账
  • 潘塔纳尔湿地位于巴拉圭盆地
  • jquery 滚动条
  • 赠送客户商品分录
  • 亚伯拉罕湖中的树,加拿大艾伯塔 (© Coolbiere/Getty Images)
  • php操作excel
  • 补缴当年增值税税款和滞纳金如何记账
  • 持有至到期投资是什么意思
  • 深度学习如何训练出好的模型
  • ps填头发
  • 发票申请条件
  • index.php备份文件
  • 三栏式明细账适用于原材料明细账
  • 企业收到国债专项资金怎么记账
  • 房租押金需要缴税吗
  • sqlserver避免死锁
  • 异地预缴税款少交了城建税怎么办
  • 建筑行业旧项目怎么处理
  • 银行承兑汇票背书转让会计分录
  • 利息收入是一级科目还是
  • 发票种类包括
  • 总账与总账之间的核对
  • 行业协会是怎么赚钱的
  • 零税率发票有法律效力吗
  • 应付账款长时间不付款怎么处理
  • 出口收汇核销单的作用
  • 工程类的增值税
  • 购入钢材
  • 税金及附加是按什么基础交的
  • 餐饮发票如何入账
  • 普通发票和增值发票的区别在哪里
  • 建账是啥意思
  • python的底层语言
  • centos 安装
  • wrsvn.exe是什么
  • ubuntu系统查看mac地址命令
  • 安装ubuntu不支持nvidia显卡
  • linux读取命令
  • fsck.mode
  • linux shell命令大全
  • win7系统笔记本怎么连接蓝牙耳机
  • linux中nfs的搭建
  • iptables 增加
  • cocos2d-x教程
  • node.js如何运行
  • linux监控网络请求
  • android怎么学
  • python 命令
  • js实现拖拽div的弹出框
  • js阻止浏览器后退
  • jquery的实现原理
  • python优先级顺序
  • python win
  • 个人所得税申诉有什么后果
  • 个人所得税是哪种税率
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设