Android 对Bitmap的一些操作记录

Android2023年1月15日 am8:08发布2年前 (2023)更新 91es.com站长
53 0 0
目录

前言

Android中对Bitmap的操作很多,比如缩放裁剪旋转等,这里简单记录一下,方便自己查阅。

PS: 参考别人内容修改,部分内容有改动和自己的理解。

正文

Matrix

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

Matrix3*3的矩阵结构

MSCALE_X MSKEW_X  MTRANS_X
MSKEW_Y  MSCALE_Y MTRANS_Y
MPERSP_0 MPERSP_1 MPERSP_2

大概对应的意思

缩放X 偏移X 平移X
偏移Y 缩放Y 平移Y
透视0 透视1 透视2

Matrix的操作有set,pre和post方法,例如缩放setScale(),preScale(),postScale()

  1. setScale(sx,sy),首先会将该Matrix设置为对角矩阵,即相当于调用reset()方法,然后在设置该Matrix的MSCALE_X和MSCALE_Y直接设置为sx,sy的值
  2. preScale(sx,sy),不会重置Matrix,而是直接与Matrix之前的MSCALE_X和MSCALE_Y值结合起来(相乘),M' = M * S(sx, sy)。
  3. postScale(sx,sy),不会重置Matrix,而是直接与Matrix之前的MSCALE_X和MSCALE_Y值结合起来(相乘),M' = S(sx, sy) * M。

缩放

PS: 这里暂时不判断source是否为null,下同

//传入指定高宽
public Bitmap scaleBitmap(Bitmap source, int width, int height) {
    int bitmapWidth = source.getWidth();
    int bitmapHeight = source.getHeight();
    float scaleWith = ((float) width) / bitmapWidth;
    float scaleHeight = ((float) height) / bitmapHeight;
    Matrix matrix = new Matrix();
    matrix.postScale(scaleWith, scaleHeight);
    return Bitmap.createBitmap(source, 0, 0, bitmapWidth, bitmapHeight, matrix, true);
}

或者

//传入缩放比
private Bitmap scaleBitmap2(Bitmap source, float scale) {
    int bitmapWidth = source.getWidth();
    int bitmapHeight = source.getHeight();
    Matrix matrix = new Matrix();
    matrix.postScale(scale, scale);
    return Bitmap.createBitmap(source, 0, 0, bitmapWidth, bitmapHeight, matrix, true);
}

裁剪

/**
 * @param source source
 * @param x      起始裁剪坐标x
 * @param y      起始裁剪坐标y
 * @param width  裁剪宽度
 * @param height 裁剪高度或叫长度
 */
private Bitmap cropBitmap(Bitmap source, int x, int y, int width, int height) {
    if (width <= 0 || height <= 0) {
        return Bitmap.createBitmap(source, 0, 0, 1, 1);
    }
    return Bitmap.createBitmap(source, x, y, width, height);
}

PS: width 和 height不能为0 ,也不能超过source对应的宽高

举个例子

//裁剪bitmap从底部开始裁剪上半部分
cropBitmap(bitmap,0, 0, bitmap.getWidth(), bitmap.getWidth()/2)
//裁剪bitmap从中心位置开始裁剪下半部
cropBitmap(bitmap0, 0, bitmap0.getHeight() / 2, bitmap0.getWidth(), bitmap.getWidth() / 2)

旋转

/**
 * @param source source
 * @param rotate [0-360]
 */
private Bitmap rotateBitmap(Bitmap source, float rotate) {
    int width = source.getWidth();
    int height = source.getHeight();
    Matrix matrix = new Matrix();
    matrix.setRotate(rotate);
    return Bitmap.createBitmap(source, 0, 0, width, height, matrix, true);
}

拼接

/**
 * source1+ source2 横[宽]向拼接在一起
 *
 * @param source1 source1
 * @param source2 source2
 */
private Bitmap mosaicBitmap(Bitmap source1, Bitmap source2) {
    Bitmap result = Bitmap.createBitmap(source1.getWidth() + source2.getWidth(),
            Math.max(source1.getHeight(), source2.getHeight()), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    canvas.drawBitmap(source1, 0, 0, null);
    canvas.drawBitmap(source2, source1.getWidth(), 0, null);
    return result;
}

或者

/**
 * source1+ source2 纵[高]向拼接在一起
 *
 * @param source1 source1
 * @param source2 source2
 */
private Bitmap mosaicBitmap2(Bitmap source1, Bitmap source2) {
    Bitmap result = Bitmap.createBitmap(Math.max(source1.getWidth(), source2.getWidth()),
            source1.getHeight() + source2.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    canvas.drawBitmap(source1, 0, 0, null);
    canvas.drawBitmap(source2, 0, source1.getHeight(), null);
    return result;
}

偏移

对于偏移,暂时没搞懂(比如kx和ky的范围以及这个功能的作用),这里只是记录一下代码。

private Bitmap skewBitmap(Bitmap source, float kx, float ky) {
    Matrix matrix = new Matrix();
    matrix.postSkew(kx, ky);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}

参考文章

  1. Android Bitmap 常见的几个操作:缩放,裁剪,旋转,偏移
  2. bitmap拼接、截图
  3. setScale,preScale和postScale的区别
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com[备用域名]
3、 本站内容: 部分来源于网络,仅供站长学习和参考,若侵权请留言
4、 本站打赏: 打赏站长一杯冰可乐 打赏站长一杯冰可乐

暂无评论

暂无评论...

随机推荐

切换语言Fragment被回收

这个最近在项目中遇到,摘抄于此。 开发过程中,页面使用fragmentactivity,可能会遇到这样的问题应用放置于后台,前台应用使用资源过多,手机默认会回收一些...

SystemServer的启动之一

前言 之前介绍过Zygote的启动流程,然后这里会forkSystemServer(),然后通过一系列最终找到SystemServer的main函数入口。 今天就进入看看SystemServer.java中...

JNI之函数的参数介绍

前言 之前学过JNI的动态注册和静态注册,到目前为止,简单的可以依葫芦画瓢了,但对于细节却还有很多的不知道。因此后面慢慢记录一下。方便自己查阅和学习。 ...

Android Studio重构清除无引用资源

前言 Android开发中,发现移植的APP模块存有很多图片和xml等资源,至于是否有引用,不去查询是不太好知道的。 但是Android Studio有个功能,也就是Android St...

梁实秋:快乐

天下最快乐的事大概莫过于做皇帝。“首出庶物,万国咸宁”。至不济可以生杀予夺,为所欲为。至于后宫粉黛三千,御膳八珍罗列,更是不在话下。清乾隆皇帝,“称八...