0

我搜索了一种从 9 个图像文件创建单个 imageView 的方法,如下所示:

IMG1 - IMG2 - IMG3

IMG4 - IMG5 - IMG6

IMG7 - IMG8 - IMG9

我看到了几个对我有帮助的有趣话题。其中一个谈论可能适合我需要的解决方案。在本主题中,Dimitar Dimitrov 提出以下建议:

您可以尝试使用原始数据,通过将图像中的像素数据提取为 32 位 int ARGB 像素数组,合并到一个大数组中,并创建一个新的位图,使用 Bitmap 类的方法,如 copyPixelsToBuffer( )、createBitmap() 和 setPixels()。来源:在 Android 的 ImageView 中渲染两个图像?

所以我可以从每个图像文件中提取 32 位 ARGB 像素,然后创建一个位图,我可以在其中使用 setPixels 函数进行填充。问题是我不知道如何“提取 32 位 ARGB每个图像文件的像素" ...

我还看到了有关 canvas 和 surfaceView 的东西,但我从不使用它们。此外,最终对象有时只会被缩放(当用户想要它时),所以我认为使用单个 imageView 使其工作会更容易......

所以我从 AsyncTask 中的这部分代码开始(以避免使用 UI 线程),但我已经得到了 OUT OF MEMORY 异常

...
@Override
protected Bitmap doInBackground(Void... params) {
     return this.createBigBitmap();
}

public Bitmap createBigBitmap() {

Bitmap pageBitmap = Bitmap.createBitmap(800, 1066, Bitmap.Config.ARGB_8888); // OUT OF MEMORY EXCEPTION

// create an ArrayList of the 9 page Parts
ArrayList<Bitmap> pageParts = new ArrayList<Bitmap>();
for(int pagePartNum = 1; pagePartNum <= 9; pagePartNum++){
    Bitmap pagePartBitmap = getPagePart(pageNum, pagePartNum);
    pageParts.add(pagePartBitmap);
}


// try to copy the content of the 9 bitmaps into a single one bitmap
int[] pixels = null;
            int offsetX = 0, offsetY = 0, pagePartNum = 0;

            for (int x = 0; x < this.nbPageRows; x++) {
                for (int y = 0; y < this.nbPageColumns; y++) {
                    pagePartNum = x * this.nbPageColumns + y;
                    Bitmap pagePartBitmap = pageParts.get(pagePartNum);
                    // read pixels from the pagePartBitmap
                    pixels = new int[pagePartBitmap.getHeight() * pagePartBitmap.getWidth()];
                    pagePartBitmap.getPixels(pixels, 0, pagePartBitmap.getWidth(), 0, 0, pagePartBitmap.getWidth(), pagePartBitmap.getHeight());

                    // compute offsetY
                    if(x == 0)
                        offsetY = 0;
                    if(x == 1)
                        offsetY = pageParts.get(0).getHeight();
                    if(x == 2)
                        offsetY = pageParts.get(0).getHeight() * 2;

                    // compute offsetX
                    if(y == 0)
                        offsetX = 0;
                    if(y == 1)
                        offsetX = pageParts.get(0).getWidth();
                    if(y == 2)
                        offsetX = pageParts.get(0).getWidth() * 2;


                    // write pixels read to the pageBitmap
                    pageBitmap.setPixels(pixels, 0, pagePartBitmap.getWidth(), offsetX, offsetY, pagePartBitmap.getWidth(), pagePartBitmap.getHeight());
                    offsetX += pagePartBitmap.getWidth();
                    offsetY += pagePartBitmap.getHeight();

                }
            }
return pageBitmap;
}

// get a bitmap from one of the 9 existing image file page part
private Bitmap getPagePart(int pageNum, int pagePartNum) {
        String imgFilename = this.directory.getAbsolutePath()
                + File.separator + "z-"
                + String.format("%04d", pageNum)
                + "-" + pagePartNum + ".jpg";
        // ajoute le bitmap de la partie de page
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
        return BitmapFactory.decodeFile(imgFilename, opt);
    }

非常感谢

4

1 回答 1

0

阅读BitmapRegionDecoder这个

编辑

查看 android 中的Efficient Bitmap Handling以摆脱 OOM 错误。使用以下代码解码您的位图。

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = 4;

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}
于 2013-02-25T11:45:45.210 回答