Android---bitmap优化

目录

Bitmap 占用内存大小计算

Bitmap | Drawable | InputStream | Byte[] 之间进行转换

Bitmap 相关方法

BitmapFactory 工厂类


Bitmap 占用内存大小计算

Bitmap 作为位图,需要读入一张图片中每一个像素点的数据,其主要占用内存的地方也正是这些像素数据。对于像素数据总大小,我们可以猜想:像素总数量 * 每个像素的字节大小,而像素总数量在矩形屏幕表现下,应该是:横向像素数量 * 纵向像素数量,结合得到:

Bitmap 内存占用 = 像素数据总大小 = 横向像素数量 * 纵向像素数量 * 每个像素的字节大小

1920 * 1080 分辨率的图片,占多少内存?

1920 * 1080 占用内存 == 1920 * 1080 * 1个像素占用内存大小

1个像素占多少内存?

单个像素的字节大小由 Bitmap 的一个配置的参数 Config 来决定。

Bitmap 中,存在一个枚举类 Config,定义了 Android 中支持的 Bitmap 配置:

Config占用字节大小(Byte)说明
ALPHA_8(1)1单透明通道
RGB_565(3)2简易 RGB 色调
ARGB_4444(4)2已废弃
ARGB_8888(5)424位真彩色
RGBA_F16(6)8Android 8.0新增(更丰富的色彩表现HDR)
HARDWARESpecialAndroid 8.0新增(Bitmap 直接存储在 graphic memory)

Bitmap | Drawable | InputStream | Byte[] 之间进行转换

1. Drawable/mipmap 下图片转换为 Bitmap

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dp);
Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.mipmap.dp);

2. Bitmap 转换为 Drawable

Drawable drawable = new BitmapDrawable(getResources(), bitmap1);

3. Bitmap 转换为 byte[]

ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] bytes = baos.toByteArray();

4. byte[] 转换为 Bitmap

Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

5. InputStream 转换成 Bitmap

InputStream is = getResources().openRawResource(id);
Bitmap bitmap = BitmapFactory.decodeStream(is);

6. InputStream 转换为 byte[]

InputStream is = getResources().openRawResource(id);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[1024 * 2];
int len = 0;

while ((len = is.read(b, 0, b.length)) != -1) {
     baos.write(b, 0, len);
     baos.flush();
}
byte[] bytes = baos.toByteArray();

Bitmap 相关方法

\bullet 判断位图内存是否已经释放

public final boolean isRecycled()

\bullet 获取位图的宽度

public final int getWidth()

\bullet 获取位图的高度

public final int getHeight()

\bullet 获取指定密度转换后的图像的宽度

public int getScaleWidth(Canvas canvas)

 \bullet 获取指定密度转换后的图像的高度

public int getScaleheight(Canvas canvas)

 \bullet 按指定的图片格式以及画质,将图片转换为输出流,即压缩图片

public boolean compress(CompressFormat format, int quality, OutputStream stream)

 \bullet 以 bitmap 为原图生成不可变得新图像,即创建新图

public static Bitmap createBitmap(Bitmap bitmap)

 \bullet 以 bitmap 为原图创建新的图像,指定新图像的宽高以及是否可变

public static Bitmap createScaledBitmap(Bitmap bitmap, int dstWidth, int dstHeight, boolean filter)

 \bullet 创建指定格式、大小的位图

public static Bitmap createBitmap(int width, int height, Config config)

 \bullet 以 bitmap 为原图,创建新的图片,指定起始坐标以及新图像的宽高

public static Bitmap createBitmap(Bitmap bitmap, int x, int y, int width, int height)

BitmapFactory 工厂类

1. Option 参数类

\bullet inJustDecodeBounds = true,不获取图片,不分配内存,但会会返回图片的高度信息。如果将这个值置为 true,那么在解码的时候将不会返回 bitmap,只会返回这个 bitmap 的尺寸。这个属性的目的是,如果你只想知道一个 bitmap 的尺寸,但又不想将其加载到内存时。这是一个非常有用的属性。

public boolean inJustDecodeBounds

\bullet inSampleSize 图片缩放的倍数,这个值是一个 int,当它小于 1 的时候,将会被当做 1 处理,如果大于 1,那么就会按照比例 1 / inSampleSize 缩小 bitmap 的宽和高,降低分辨率,大于 1 时这个值将会被处置为 2 的倍数。例如,width = 100, height = 100,inSampleSize = 2,那么就会将 bitmap 处理为,width = 50, height = 50,宽高将为 1/2, 像素数将为 1/4 (1/2 * 1/2).

public int inSampleSize

\bullet 获取图片的宽度值

public int outWidth

\bullet 获取图片的高度值,表示这个 Bitmap 的宽和高,一般和 inJustDecodeBounds 一起使用来获得 Bitmap 的宽高,但是不加载到内存。

public int outHeight

\bullet 用于位图的像素压缩比

public int inDensity

\bullet 用于目标位图的像素压缩比(要生成的位图)

public int inTargetDensity

\bullet 创建临时文件,将图片存储

public byte[] inTempStorage

\bullet 设置为 true 时进行图片压缩,从 inDensity 到 inTargetDensity

public boolean inScaled

\bullet 当存储 Pixel 的内存空间在系统内存不足时是否可以被回收

public boolean inPurgeable

\bullet 配置 Bitmap 是否可以更改,比如:在 Bitmap 上隔几个像素加一条线段

public boolean inMutable

\bullet 当前屏幕的像素密度

public int inScreenDensity

2. 工厂方法

\bullet 从文件读取图片

public static Bitmap decodeFile(String pathName, Options opts)
public static Bitmap decodeFile(String pathName)

\bullet 从输入流读取图片

public static Bitmap decodeStream(InputStream is)
public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts)

\bullet 从资源文件读取图片,res 参数直接输入 getResources() 

public static Bitmap decodeResource(Resources res, int id)
public static Bitmap decodeResource(Resources res, int id, Options opts)

\bullet 从数组读取图片

public static Bitmap decodeByteArray(byte[] data, int offset, int length)
public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts)

\bullet 从文件读取文件,与 decodeFile 不同的是这个直接调用 JNI 函数进行读取,效率比较高

public static Bitmap decodeFileDescriptor(FileDescriptor fd)
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts)

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 要在 Android 上合成多个 Bitmap 图片,可以使用 Canvas 类和 Bitmap 类。下面是一个简单的示例: 1. 创建一个空的 Bitmap 对象,作为最终合成的图片: ```java Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(result); ``` 2. 将需要合成的 Bitmap 依次绘制到空的 Bitmap 上: ```java canvas.drawBitmap(bitmap1, x1, y1, null); canvas.drawBitmap(bitmap2, x2, y2, null); canvas.drawBitmap(bitmap3, x3, y3, null); ``` 3. 最后,可以保存合成后的 Bitmap 为图片文件或者显示在 ImageView 中: ```java imageView.setImageBitmap(result); ``` 完整的代码示例: ```java public Bitmap mergeBitmaps(Bitmap bitmap1, Bitmap bitmap2, Bitmap bitmap3) { int width = bitmap1.getWidth(); int height = bitmap1.getHeight() + bitmap2.getHeight() + bitmap3.getHeight(); Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(result); canvas.drawBitmap(bitmap1, 0, 0, null); canvas.drawBitmap(bitmap2, 0, bitmap1.getHeight(), null); canvas.drawBitmap(bitmap3, 0, bitmap1.getHeight() + bitmap2.getHeight(), null); return result; } ``` 以上代码将三个 Bitmap 垂直合成为一个 Bitmap,第一个 Bitmap 在最上面,第二个在中间,第三个在最下面。可以根据实际需求修改代码。 ### 回答2: Android中合成bitmap图片可以使用Canvas和Paint类来实现。步骤如下: 1. 创建一个新的Bitmap对象,用于存储合成后的图片。 2. 创建一个Canvas对象,并将新的Bitmap对象与Canvas关联起来。 3. 创建一个Paint对象,并设置相关的合成属性,如颜色、透明度、画笔风格等。 4. 使用Canvas的drawBitmap()方法将多个Bitmap对象绘制到新的Bitmap上,实现图片的合成效果。 5. 最后,可以将合成后的Bitmap保存到本地文件或者显示在界面上。 以下是一个简单的示例代码: ```java // 创建合成后的Bitmap对象 Bitmap resultBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); // 创建Canvas对象,并与新的Bitmap关联 Canvas canvas = new Canvas(resultBitmap); // 创建Paint对象 Paint paint = new Paint(); // 设置合成属性 paint.setColor(Color.RED); paint.setAlpha(128); paint.setStyle(Paint.Style.FILL); // 绘制bitmap1 canvas.drawBitmap(bitmap1, matrix1, paint); // 绘制bitmap2 canvas.drawBitmap(bitmap2, matrix2, paint); // 绘制bitmap3 canvas.drawBitmap(bitmap3, matrix3, paint); // 可以依次绘制更多的bitmap ... // 保存合成后的Bitmap到本地文件 resultBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); ``` 以上代码中,width和height表示合成后的Bitmap的宽度和高度,bitmap1、bitmap2、bitmap3等表示待合成的原始Bitmap对象,matrix1、matrix2、matrix3等表示对相应的Bitmap进行变换的Matrix对象。 通过以上步骤,就可以实现Android中的Bitmap图片合成。 ### 回答3: Android中的Bitmap是一个表示图像的类,可以用来显示图片、进行图像处理等操作。要实现Bitmap的图片合成,可以通过以下步骤: 1. 创建一个新的Bitmap对象,用于存储合成后的图片。可以使用Bitmap的createBitmap()方法,指定宽度、高度和颜色格式创建一个空白的Bitmap对象。 2. 获取要合成的原始图片。可以使用BitmapFactory的decodeResource()方法,从资源文件中加载图片,并通过BitmapFactory.Options对象设置图片的缩放比例、色彩模式等参数。 3. 将原始图片绘制到新的Bitmap对象上。可以使用Canvas的drawBitmap()方法,在新的Bitmap上绘制原始图片。可以设置合成图片的位置、大小等属性。 4. 如果需要合成多张图片,重复步骤2和步骤3,将其他图片依次绘制到新的Bitmap对象上。 5. 最后,可以将合成后的Bitmap对象进行保存或显示。可以使用Bitmap的compress()方法将Bitmap对象保存到指定的输出流中,或使用ImageView等控件的setImageBitmap()方法显示合成后的图片。 需要注意的是,图片合成可能会消耗较大的内存和处理时间,特别是在合成大尺寸图片或大量图片时。为了避免内存溢出和性能问题,可以适当进行图片的压缩、缩放或分块处理,或使用异步处理方式进行合成。此外,可以通过Bitmap的回收和复用来优化内存使用。 总之,通过创建新的Bitmap对象,获取原始图片,绘制到新的Bitmap上,就可以实现Android中的图片合成功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别偷我的猪_09

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值