android bitmap 偏移,Android Bitmap 常见的几个操作:缩放,裁剪,旋转,偏移

这篇博客详细介绍了如何使用Android中的Bitmap和Matrix类进行图像处理,包括按指定尺寸缩放、按比例缩放、裁剪、顺时针和逆时针旋转以及偏移效果。提供了相应的代码示例,展示了如何通过Matrix的set、pre和post方法来实现这些变换,并探讨了当缩放比例为1时新旧Bitmap共享内存的问题。
摘要由CSDN通过智能技术生成

Android Bitmap 相关操作

常见的几个操作:缩放,裁剪,旋转,偏移

5a28247424df6bdcfae04706a40383e2.png 

a70c37001f675d1e3c8cd3490208e410.png 

d28bf51ed33005fba65ed2047882a654.png 

17cdc2860b20d2c825dd1843f01f308e.png 

19454c2de84a830edf808402141e8a91.png

很多操作需要 Matrix 来支持;Matrix 通过矩阵来处理位图,计算出各个像素点的位置,从而把bitmap显示出来。

matrix里有一个3x3的矩阵,用于图像处理:

MSCALE_X MSKEW_X MTRANS_XMSKEW_Y MSCALE_Y MTRANS_YMPERSP_0 MPERSP_1 MPERSP_2

根据变量名能猜出具体的用途:

缩放X 偏移X 平移X

偏移Y 缩放Y 平移Y

透视0 透视1 透视2

matrix的操作有set,pre和post;set能够直接设置矩阵中的数值;pre类似于矩阵左乘;post类似与矩阵中的右乘

原bitmap经过计算后,会重新生成一张bitmap

代码片段:

/*** 根据给定的宽和高进行拉伸 * *@paramorigin 原图 *@paramnewWidth 新图的宽 *@paramnewHeight 新图的高 *@returnnew Bitmap*/ private Bitmap scaleBitmap(Bitmap origin, int newWidth, intnewHeight) {if (origin == null) {return null; }int height =origin.getHeight();int width =origin.getWidth();float scaleWidth = ((float) newWidth) /width;float scaleHeight = ((float) newHeight) /height; Matrix matrix= newMatrix(); matrix.postScale(scaleWidth, scaleHeight);//使用后乘 Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);if (!origin.isRecycled()) { origin.recycle(); }returnnewBM; }/*** 按比例缩放图片 * *@paramorigin 原图 *@paramratio 比例 *@return新的bitmap*/ private Bitmap scaleBitmap(Bitmap origin, floatratio) {if (origin == null) {return null; }int width =origin.getWidth();int height =origin.getHeight(); Matrix matrix= newMatrix(); matrix.preScale(ratio, ratio); Bitmap newBM= Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);if(newBM.equals(origin)) {returnnewBM; } origin.recycle();returnnewBM; }/*** 裁剪 * *@parambitmap 原图 *@return裁剪后的图像*/ privateBitmap cropBitmap(Bitmap bitmap) {int w = bitmap.getWidth(); //得到图片的宽,高 int h =bitmap.getHeight();int cropWidth = w >= h ? h : w;//裁切后所取的正方形区域边长 cropWidth /= 2;int cropHeight = (int) (cropWidth / 1.2);return Bitmap.createBitmap(bitmap, w / 3, 0, cropWidth, cropHeight, null, false); }/*** 选择变换 * *@paramorigin 原图 *@paramalpha 旋转角度,可正可负 *@return旋转后的图片*/ private Bitmap rotateBitmap(Bitmap origin, floatalpha) {if (origin == null) {return null; }int width =origin.getWidth();int height =origin.getHeight(); Matrix matrix= newMatrix(); matrix.setRotate(alpha);//围绕原地进行旋转 Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);if(newBM.equals(origin)) {returnnewBM; } origin.recycle();returnnewBM; }/*** 偏移效果 *@paramorigin 原图 *@return偏移后的bitmap*/ privateBitmap skewBitmap(Bitmap origin) {if (origin == null) {return null; }int width =origin.getWidth();int height =origin.getHeight(); Matrix matrix= newMatrix(); matrix.postSkew(-0.6f, -0.3f); Bitmap newBM= Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);if(newBM.equals(origin)) {returnnewBM; } origin.recycle();returnnewBM; }

按钮的操作定义:

@Overridepublic voidonClick(View v) { Bitmap originBM=BitmapFactory.decodeResource(getResources(), R.drawable.littleboygreen_x128);switch(v.getId()) {case R.id.btn1: {//按尺寸缩放effectTextView.setText(R.string.scale); Bitmap nBM= scaleBitmap(originBM, 100, 72); effectView.setImageBitmap(nBM);break; }case R.id.btn2: {//按比例缩放,每次点击缩放比例都会不同effectTextView.setText(R.string.scale_ratio);if (ratio < 3) { ratio+= 0.05f; }else{ ratio= 0.1f; } Bitmap nBM=scaleBitmap(originBM, ratio); effectView.setImageBitmap(nBM);break; }case R.id.btn3: {//裁剪 effectTextView.setText("剪个头"); Bitmap cropBitmap=cropBitmap(originBM); effectView.setImageBitmap(cropBitmap);break; }case R.id.btn4: {//顺时针旋转效果;每次点击更新旋转角度 if (alpha < 345) { alpha+= 15; }else{ alpha= 0; } effectTextView.setText("旋转"); Bitmap rotateBitmap=rotateBitmap(originBM, alpha); effectView.setImageBitmap(rotateBitmap);break; }case R.id.btn5: {//逆时针旋转效果;每次点击更新旋转角度 if (beta > 15) { beta-= 15; }else{ beta= 360; } effectTextView.setText("旋转"); Bitmap rotateBitmap=rotateBitmap(originBM, beta); effectView.setImageBitmap(rotateBitmap);break; }case R.id.btn6: {//偏移效果;偏移量在方法中 Bitmap skewBM =skewBitmap(originBM); effectView.setImageBitmap(skewBM);break; } } }

遇到的问题

Matrix matrix = newMatrix();matrix.preScale(ratio, ratio);//当 ratio=1,下面的 newBM 将会等价于 originBitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);if (!origin.isRecycled()) {origin.recycle();}

log如下,当ratio=1时,新bitmap和旧的bitmap同一地址

2021年05月27日 05:27:16.086 1672021年05月27日723/? D/rust: originBitmap = android.graphics.Bitmap@1e8849e

2021年05月27日 05:27:16.086 1672021年05月27日723/? D/rust: newBitmap = android.graphics.Bitmap@1e8849e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值