您的位置:

Android Bitmap详解

一、Android BitmapFactory

Android中的BitmapFactory类提供了一系列用于初始化Bitmap的方法。其中最常用的方法是decodeFile(),该方法可以从一个指定文件的路径中读取一个Bitmap对象。下面是一个简单的示例:


Bitmap bitmap = BitmapFactory.decodeFile(filePath);
imageView.setImageBitmap(bitmap);

除了decodeFile()方法之外,BitmapFactory还提供了其他方法用于从不同来源加载Bitmap,例如decodeResource()用于从资源文件中加载;decodeStream()用于从输入流中加载。

二、Android Bitmap缩放

缩放Bitmap是一种常见的操作,Android提供了几种方法可以实现Bitmap的缩放。其中最常用的方法是createScaledBitmap(),该方法可以创建一个新的Bitmap对象,该对象是原始Bitmap对象缩放后的结果。


Bitmap originalBitmap = BitmapFactory.decodeFile(filePath);
int originalWidth = originalBitmap.getWidth();
int originalHeight = originalBitmap.getHeight();

float scaleWidth = ((float) newWidth) / originalWidth;
float scaleHeight = ((float) newHeight) / originalHeight;

Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);

Bitmap newBitmap = Bitmap.createBitmap(originalBitmap, 0, 0, originalWidth, originalHeight, matrix, true);
imageView.setImageBitmap(newBitmap);

这里,我们使用了Matrix类来进行缩放操作。通过计算原始Bitmap与目标Bitmap的宽高比例,然后通过Matrix.postScale()方法来设置缩放比例。最后,我们生成新的Bitmap对象,调用createBitmap()方法,传入原始Bitmap的信息、Matrix对象以及是否开启抗锯齿选项。

三、Android Bitmap旋转

Android提供了RotateAnimation类可以实现View的旋转动画效果。但如果我们需要对Bitmap进行旋转,我们可以使用Matrix类的方法实现。下面是一个示例:


Bitmap originalBitmap = BitmapFactory.decodeFile(filePath);

Matrix matrix = new Matrix();
matrix.postRotate(degree);

Bitmap newBitmap = Bitmap.createBitmap(originalBitmap, 0, 0, originalBitmap.getWidth(), originalBitmap.getHeight(), matrix, true);

imageView.setImageBitmap(newBitmap);

我们使用Matrix.postRotate()方法来进行旋转操作,并传入旋转的角度。然后,我们使用Bitmap.createBitmap()创建新的Bitmap对象,并将原始Bitmap、Matrix对象以及是否开启抗锯齿选项作为参数传入。

四、Android Bitmap像素增大

在有些情况下,我们需要将Bitmap对象的像素大小进行增大。如果我们将原始Bitmap的像素进行分离,然后将它们复制到新的Bitmap对象中,就可以实现像素的增大功能。下面是一个示例:


Bitmap originalBitmap = BitmapFactory.decodeFile(filePath);
int originalWidth = originalBitmap.getWidth();
int originalHeight = originalBitmap.getHeight();

int width = originalWidth * 2;
int height = originalHeight * 2;

Bitmap newBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

int[] pixels = new int[originalWidth * originalHeight];
originalBitmap.getPixels(pixels, 0, originalWidth, 0, 0, originalWidth, originalHeight);

int[] biggerPixels = new int[width * height];
for (int i = 0; i < originalHeight; i++) {
    for (int j = 0; j < originalWidth; j++) {
        int pixel = pixels[i * originalWidth + j];
        biggerPixels[(i * 2) * width + (j * 2)] = pixel;
        biggerPixels[(i * 2) * width + (j * 2 + 1)] = pixel;
        biggerPixels[(i * 2 + 1) * width + (j * 2)] = pixel;
        biggerPixels[(i * 2 + 1) * width + (j * 2 + 1)] = pixel;
    }
}

newBitmap.setPixels(biggerPixels, 0, width, 0, 0, width, height);

imageView.setImageBitmap(newBitmap);

这里,我们使用了Bitmap.getPixels()方法获取原始Bitmap的像素值,并使用一个新的像素数组biggerPixels来存储增大后的像素。接着,我们使用Bitmap.setPixels()方法将新的像素数组应用到新的Bitmap对象中。

五、Android Bitmap转byte

有时候,我们需要将Bitmap转换为byte数组。这个操作非常简单,只需要调用Bitmap的compress()方法即可。下面是一个示例:


Bitmap bitmap = BitmapFactory.decodeFile(filePath);

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

imageView.setImageBitmap(bitmap);

这里,我们使用了ByteArrayOutputStream来接收byte数组,使用Bitmap.compress()方法将Bitmap转换成PNG格式,并传入压缩质量参数以及指定输出流。

六、Android Bitmap压缩

在开发中,我们经常需要对Bitmap进行压缩,以便减少内存占用。Android提供了多种方法可以实现Bitmap的压缩,其中最简单的方法是使用Bitmap.compress()方法。下面是一个示例:


Bitmap originalBitmap = BitmapFactory.decodeFile(filePath);
ByteArrayOutputStream stream = new ByteArrayOutputStream();

originalBitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream);

byte[] byteArray = stream.toByteArray();
Bitmap compressedBitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);

imageView.setImageBitmap(compressedBitmap);

我们使用ByteArrayOutputStream来接收压缩后的byte数组,并将Bitmap对象压缩为JPEG格式,设置压缩质量参数。最后,我们使用BitmapFactory.decodeByteArray()方法将压缩后的byte数组转换为Bitmap对象,并将其设置到ImageView中。

七、Android Bitmap内存

在处理Bitmap对象时,我们需要注意内存使用问题。有些情况下,我们将Bitmap加载到内存中,但是没有适时将其释放,导致内存占用过大。因此,我们建议在使用完Bitmap对象之后,调用Bitmap.recycle()方法进行释放。下面是一个示例:


if (bitmap != null) {
    if (!bitmap.isRecycled()) {
        bitmap.recycle();
    }
    bitmap = null;
}

这里,我们首先判断Bitmap对象是否为空,然后判断Bitmap对象是否已经被回收。如果Bitmap对象未被回收,则调用recycle()方法进行回收。最后,我们将Bitmap对象置为null,以避免内存泄漏。

八、Android Bitmap优化

下面是一些优化Bitmap对象占用内存的建议:

  1. 在加载大尺寸的Bitmap时,可以使用inSampleSize参数对图片进行压缩。inSampleSize参数用于指定图片的缩小比例,以便减少内存使用。
  2. 避免对Bitmap对象进行不必要的操作,如旋转或缩放。
  3. 使用ARGB_8888格式的Bitmap对象,该格式可以保存透明度信息,并提供更好的图像质量。
  4. 在处理一系列Bitmap对象时,可以考虑使用Bitmap占用内存更小的RGB_565格式。

九、Android Bitmap复用

在加载大量Bitmap对象时,我们可以考虑使用BitmapFactory.Options的inBitmap参数来复用Bitmap对象。该参数用于指定要复用的Bitmap对象,以便减少内存使用。下面是一个示例:


BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inSampleSize = 4;
options.inBitmap = bitmapToReuse;

Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);

imageView.setImageBitmap(bitmap);

这里,我们创建了一个BitmapFactory.Options对象,并设置了inBitmap属性为要复用的Bitmap对象。接着,我们使用BitmapFactory.decodeFile()方法来加载Bitmap,并将Options对象作为参数进行传递。

十、Android Bitmap裁剪选取

有时候,我们需要对Bitmap进行裁剪或选取。Android提供了Bitmap.createBitmap()方法,可以从原始Bitmap对象中选取一块区域,生成一个新的Bitmap对象。下面是一个示例:


Bitmap originalBitmap = BitmapFactory.decodeFile(filePath);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap, startX, startY, width, height);
imageView.setImageBitmap(newBitmap);

这里,我们使用Bitmap.createBitmap()方法来创建一个新的Bitmap对象。该方法需要传入原始Bitmap对象,以及需要选取的区域的坐标和大小。