位置: 编程技术 - 正文
推荐整理分享木瓜妮子多媒体开发教程---第二天---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 = X0.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
});
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文件里使用的命令)
友情链接: 武汉网站建设