位图 "images" 传递给另一个 activity(内存不足)
Bitmap "images" pass to another activity (Out of memory)
请先阅读完整问题,然后再将其标记为重复或投反对票。
我正在开发一个应用程序,它可以切开图片和 运行 google 视觉来识别每个块或图片切片中的文本和 运行 OCR 来检测圆圈泡泡是否在块中被填充。但是当我将位图图像切片到数组中并将其传递给其他 activity 以进行处理时,它会因过度使用内存而崩溃。我知道我可以压缩它,但我已经尝试过了(虽然我不想压缩它,因为我需要 运行 google 视觉并且可能无法准确提取文本)但它没有用,因为有 46 片图像。我怎么能不上传到云上就重新获取它以进行处理,因为这可能需要很长时间。也非常欢迎任何替代解决方案。我被困在这个问题上有一段时间了。
import android.content.Intent;.....
public class ProcessesdResult extends AppCompatActivity {
TextView tvProcessedText;
Button btnImageSlice;
Bitmap image;
int chunkNumbers =46;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_processesd_result);
Intent intenttakeattendance = getIntent();
String fname = intenttakeattendance.getStringExtra("fname");
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root);
String photoPath = myDir+"/sams_images/"+ fname;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
image = BitmapFactory.decodeFile(photoPath, options);
btnImageSlice=findViewById(R.id.btnimageslice);
btnImageSlice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
splitImage(image, chunkNumbers) ;
}
});
}
private void splitImage(Bitmap image, int chunkNumbers) {
//For the number of rows and columns of the grid to be displayed
int rows =23;
int cols =2;
//For height and width of the small image chunks
int chunkHeight,chunkWidth;
//To store all the small image chunks in bitmap format in this list
ArrayList<Bitmap> chunkedImages = new ArrayList<Bitmap>(chunkNumbers);
//Getting the scaled bitmap of the source image
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, image.getWidth(), image.getHeight(), true);
chunkHeight = image.getHeight()/rows;
chunkWidth = image.getWidth()/cols;
//xCoord and yCoord are the pixel positions of the image chunks
int yCoord = 0;
for(int x=0; x<rows; x++){
int xCoord = 0;
for(int y=0; y<cols; y++){
chunkedImages.add(Bitmap.createBitmap(scaledBitmap, xCoord, yCoord, chunkWidth, chunkHeight));
xCoord += chunkWidth;
}
yCoord += chunkHeight;
}
//Start a new activity to show these chunks into a grid
Intent intent = new Intent(ProcessesdResult.this, ChunkedImageActivity.class);
intent.putParcelableArrayListExtra("image chunks", chunkedImages);
startActivity(intent);
}
}
这是我要切片的图像类型
您不想在活动之间传递对象,尤其是像位图这样的大对象。我建议将您的位图保存在设备文件系统中,然后传递一个 URI 列表。像这样保存位图并在使用完位图后回收位图也应该减少在切片图像的循环期间的 RAM 使用量。
关于将位图保存为文件,我会参考这个问题:Saving and Reading Bitmaps/Images from Internal memory in Android
所以基本上你的循环应该是这样的:
for(int x=0; x<rows; x++){
int xCoord = 0;
for(int y=0; y<cols; y++){
Bitmap image = Bitmap.createBitmap(scaledBitmap, xCoord, yCoord, chunkWidth, chunkHeight);
Uri uri = saveBitmapAsFile(image);
image.recycle();
xCoord += chunkWidth;
}
yCoord += chunkHeight;
}
在清单中使用 android:largeHeap="true" 如果您仍然遇到相同的错误,请尝试以下操作:
而不是发送 "intent.putParcelableArrayListExtra(" 图像块”,chunkedImages);”
位图到另一个 activity,将该图像保存到本地存储并在任何你想要的地方使用路径。
我建议使用静态创建另一个数据(位图)存储 class。
使用此 class 保存位图并调用另一个 activity 进行读取。
This link 有帮助。
请先阅读完整问题,然后再将其标记为重复或投反对票。
我正在开发一个应用程序,它可以切开图片和 运行 google 视觉来识别每个块或图片切片中的文本和 运行 OCR 来检测圆圈泡泡是否在块中被填充。但是当我将位图图像切片到数组中并将其传递给其他 activity 以进行处理时,它会因过度使用内存而崩溃。我知道我可以压缩它,但我已经尝试过了(虽然我不想压缩它,因为我需要 运行 google 视觉并且可能无法准确提取文本)但它没有用,因为有 46 片图像。我怎么能不上传到云上就重新获取它以进行处理,因为这可能需要很长时间。也非常欢迎任何替代解决方案。我被困在这个问题上有一段时间了。
import android.content.Intent;.....
public class ProcessesdResult extends AppCompatActivity {
TextView tvProcessedText;
Button btnImageSlice;
Bitmap image;
int chunkNumbers =46;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_processesd_result);
Intent intenttakeattendance = getIntent();
String fname = intenttakeattendance.getStringExtra("fname");
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root);
String photoPath = myDir+"/sams_images/"+ fname;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
image = BitmapFactory.decodeFile(photoPath, options);
btnImageSlice=findViewById(R.id.btnimageslice);
btnImageSlice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
splitImage(image, chunkNumbers) ;
}
});
}
private void splitImage(Bitmap image, int chunkNumbers) {
//For the number of rows and columns of the grid to be displayed
int rows =23;
int cols =2;
//For height and width of the small image chunks
int chunkHeight,chunkWidth;
//To store all the small image chunks in bitmap format in this list
ArrayList<Bitmap> chunkedImages = new ArrayList<Bitmap>(chunkNumbers);
//Getting the scaled bitmap of the source image
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, image.getWidth(), image.getHeight(), true);
chunkHeight = image.getHeight()/rows;
chunkWidth = image.getWidth()/cols;
//xCoord and yCoord are the pixel positions of the image chunks
int yCoord = 0;
for(int x=0; x<rows; x++){
int xCoord = 0;
for(int y=0; y<cols; y++){
chunkedImages.add(Bitmap.createBitmap(scaledBitmap, xCoord, yCoord, chunkWidth, chunkHeight));
xCoord += chunkWidth;
}
yCoord += chunkHeight;
}
//Start a new activity to show these chunks into a grid
Intent intent = new Intent(ProcessesdResult.this, ChunkedImageActivity.class);
intent.putParcelableArrayListExtra("image chunks", chunkedImages);
startActivity(intent);
}
}
这是我要切片的图像类型
您不想在活动之间传递对象,尤其是像位图这样的大对象。我建议将您的位图保存在设备文件系统中,然后传递一个 URI 列表。像这样保存位图并在使用完位图后回收位图也应该减少在切片图像的循环期间的 RAM 使用量。
关于将位图保存为文件,我会参考这个问题:Saving and Reading Bitmaps/Images from Internal memory in Android
所以基本上你的循环应该是这样的:
for(int x=0; x<rows; x++){
int xCoord = 0;
for(int y=0; y<cols; y++){
Bitmap image = Bitmap.createBitmap(scaledBitmap, xCoord, yCoord, chunkWidth, chunkHeight);
Uri uri = saveBitmapAsFile(image);
image.recycle();
xCoord += chunkWidth;
}
yCoord += chunkHeight;
}
在清单中使用 android:largeHeap="true" 如果您仍然遇到相同的错误,请尝试以下操作: 而不是发送 "intent.putParcelableArrayListExtra(" 图像块”,chunkedImages);” 位图到另一个 activity,将该图像保存到本地存储并在任何你想要的地方使用路径。
我建议使用静态创建另一个数据(位图)存储 class。 使用此 class 保存位图并调用另一个 activity 进行读取。
This link 有帮助。