gpt4 book ai didi

java - Android 位图内存不足

转载 作者:行者123 更新时间:2023-12-02 02:31:15 25 4
gpt4 key购买 nike

我正在创建一个应用程序,它从相机获取图像(使用 CameraKit 库),处理图像并使用 Google Vision Api 进行 OCR 读取,并收到此错误:

FATAL EXCEPTION: main Process: com.., PID: 1938 java.lang.OutOfMemoryError: Failed to allocate a 63701004 byte allocation with 16777216 free bytes and 60MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.Bitmap.nativeCreate(Native Method) at android.graphics.Bitmap.createBitmap(Bitmap.java:905) at android.graphics.Bitmap.createBitmap(Bitmap.java:882) at android.graphics.Bitmap.createBitmap(Bitmap.java:849) at com.****.****.Reader.ReaderResultActivity.createContrast(ReaderResultActivity.java:123) at com.*****.****.Reader.ReaderResultActivity.onCreate(ReaderResultActivity.java:47) at android.app.Activity.performCreate(Activity.java:6672) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2612) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6123) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)

ReaderResultActivity 代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reader_result);

ImageView img1 = (ImageView)findViewById(R.id.imageView2);
ImageView img2 = (ImageView)findViewById(R.id.imageView3);
ImageView img3 = (ImageView)findViewById(R.id.imageView4);
TextView scanResults = (TextView)findViewById(R.id.textView);

//Get bitmap from a static class.
Bitmap bitmap = Reader.img;

Bitmap grayScale = toGrayscale(bitmap);
Bitmap blackWhiteImage = createContrast(grayScale, 50);
Bitmap invertColor = invertColor(blackWhiteImage);

//Show process steps
img1.setImageBitmap(grayScale);
img2.setImageBitmap(blackWhiteImage);
img3.setImageBitmap(invertColor);

TextRecognizer detector = new TextRecognizer.Builder(getApplicationContext()).build();

try {

if (detector.isOperational()) {
Frame frame = new Frame.Builder().setBitmap(invertColor).build();
SparseArray<TextBlock> textBlocks = detector.detect(frame);
String blocks = "";
String lines = "";
String words = "";
for (int index = 0; index < textBlocks.size(); index++) {
//extract scanned text blocks here
TextBlock tBlock = textBlocks.valueAt(index);
blocks = blocks + tBlock.getValue() + "\n" + "\n";
for (Text line : tBlock.getComponents()) {
//extract scanned text lines here
lines = lines + line.getValue() + "\n";
for (Text element : line.getComponents()) {
//extract scanned text words here
words = words + element.getValue() + ", ";
}
}
}
if (textBlocks.size() == 0) {
scanResults.setText("Scan Failed: Found nothing to scan");
} else {
lines = lines.replaceAll("o", "0");
lines = lines.replaceAll("A", "1");

scanResults.setText(lines + "\n");
}
} else {
scanResults.setText("Could not set up the detector!");
}
} catch (Exception e) {
Toast.makeText(this, "Failed to load Image", Toast.LENGTH_SHORT)
.show();
Log.e("312", e.toString());
}
}

private Bitmap processImage(Bitmap bitmap){
Bitmap grayScale = toGrayscale(bitmap);
Bitmap blackWhiteImage = createContrast(grayScale, 50);
Bitmap invertColor = invertColor(blackWhiteImage);

return invertColor;
}
public Bitmap toGrayscale(Bitmap bmpOriginal) {
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();

Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, bmpOriginal.getConfig());
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}

public static Bitmap createContrast(Bitmap src, double value) {
// image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// get contrast value
double contrast = Math.pow((100 + value) / 100, 2);

// scan through all pixels
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get pixel color
pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
// apply filter contrast for every channel R, G, B
R = Color.red(pixel);
R = (int)(((((R / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
if(R < 0) { R = 0; }
else if(R > 255) { R = 255; }

G = Color.red(pixel);
G = (int)(((((G / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
if(G < 0) { G = 0; }
else if(G > 255) { G = 255; }

B = Color.red(pixel);
B = (int)(((((B / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
if(B < 0) { B = 0; }
else if(B > 255) { B = 255; }

// set new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}

return bmOut;
}

Bitmap invertColor(Bitmap src){
Bitmap copy = src.copy(src.getConfig(), true);

for (int x = 0; x < copy.getWidth(); ++x) {
for (int y = 0; y < copy.getHeight(); ++y) {
int color = copy.getPixel(x, y);
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
int avg = (r + g + b) / 3;
int newColor = Color.argb(255, 255 - avg, 255 - avg, 255 - avg);
copy.setPixel(x, y, newColor);
}
}


return copy;
}

已经尝试在 list 中执行此操作

android:largeHeap="true"

但是应用程序在打开时停止运行:

ReaderResultActivity.createContrast(ReaderResultActivity.java:123)

出现错误时没有“largeHeap”标记的同一行。只是不知道该怎么做,但我认为每个处理函数中的所有“Bitmap.CreateBitmap”都有一些东西。但如果不这样做,在OCR读取时,会出现错误,说位图格式错误。

最佳答案

您正在不同的 ImageView 中加载三个位图,而没有根据您想要在 UI 上显示的大小进行缩放。

Android 设备的相机拍摄的图片分辨率远高于设备的屏幕密度。

鉴于您使用的内存有限,理想情况下您只想在内存中加载较低分辨率的版本。较低分辨率版本应与显示它的 UI 组件的大小相匹配。具有更高分辨率的图像不会提供任何明显的好处,但仍然会占用宝贵的内存,并且由于额外的动态缩放而产生额外的性能开销。

您可以按照开发人员文档建议对其进行优化 - https://developer.android.com/topic/performance/graphics/load-bitmap.html

关于java - Android 位图内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47048947/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com