您好我正在创建图像编辑应用程序我是否为canvas和imageview创建位图
这里我在imageView中使用 385kb 图像文件 2000x2000 维度
我的问题是,我第一次使用其他小图像和编辑图像创建位图时,它会工作一段时间,但是第二次使用上面的尺寸和尺寸,它会生成java.lang.OutOfMemoryError :(
这是我的相关方法代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initialize variable
init();
// initialize view
initView();
// initialize view's event listener
initEventListener();
setImageToImageView(ims);
}
private void init() {
context = MainActivity.this;
db_colorImage = new DB_ColorImage(context);
AppUtils.setColorPreference(MainActivity.this, AppConstant.PREF_COLOR_PIC, "FF0000");
AppUtils.setComboColorPreference(MainActivity.this, AppConstant.PREF_COMBO, 1);
openCatId = getIntent().getIntExtra("open_cat_id", -1);
openCat = getIntent().getStringExtra("image_categoryname");
openImgName = getIntent().getStringExtra("img_name");
db_colorImage.openDB();
db_colorImage.startTransaction();
assetsImgxx = db_colorImage.getXXX(openCatId);
db_colorImage.successfullTransaction();
db_colorImage.completeTransaction();
db_colorImage.closeDB();
assetsAndSdImage = new ArrayList<>(getIntent().getStringArrayListExtra("again")); // aa list edit karelu with sdcard image
try {
ims = getAssets().open(openCat + "/" + openImgName);
} catch (IOException e) {
File getFromSd = new File(AppUtils.appFolder() + File.separator + openImgName);
try {
ims = new FileInputStream(getFromSd);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
public void setImageToImageView(InputStream ims) {
Drawable d = Drawable.createFromStream(ims, null);
BitmapDrawable drawable = (BitmapDrawable) d;
Bitmap bmp = drawable.getBitmap();
if (bmp != null) {
_alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888); // here i used ARGB_8888 because jnibitmap.cpp also use ARGB_8888. If we do not use this it wont color on image
}
Canvas canvas = new Canvas(_alteredBitmap);
Paint paint = new Paint();
Matrix matrix = new Matrix();
canvas.drawBitmap(bmp, matrix, paint);
imageView.setImageBitmap(_alteredBitmap); // we can also use imageView.setImageResource(R.drawable.test_image);
// ******* clear bitmap after use *******
// check after done this step it will not produce any problem
if (bmp != null) {
bmp.recycle();
bmp = null;
}
}
_alteredBitmap = Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),Bitmap.Config.ARGB_8888);
在这行我获得EXCEPTION,这是日志
01-27 19:12:33.590 27252-27252/? E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
at android.graphics.Bitmap.createBitmap(Bitmap.java:620)
at com.yptech.myfloodfilldemo.ui.MainActivity.setImageToImageView(MainActivity.java:387)
at com.yptech.myfloodfilldemo.ui.MainActivity.onCreate(MainActivity.java:96)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
编辑图像后,我保存此图像,因此我不想降低图像质量,因此我使用 Bitmap.Config.ARGB_8888 。我在位图上尝试了很多像android developer document这样的解决方案,但它对我不起作用。
是OutOfMemoryError取决于图像大小和尺寸???以及如何在createBitmap ??
时解决OutOfMemoryError的问题当我使用largHeap它工作正常但是更好的方法使用 android:largeHeap =&#34; true&#34; ??
提前感谢:)
答案 0 :(得分:2)
在使用之前优化位图。
Bitmap bitmap = MediaOptimize.reduceResolution(mediaPath, width, height);
功能:
public Bitmap reduceResolution(String filePath, int viewWidth, int viewHeight) {
int reqHeight = viewHeight;
int reqWidth = viewWidth;
BitmapFactory.Options options = new BitmapFactory.Options();
// First decode with inJustDecodeBounds=true to check dimensions
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
double viewAspectRatio = 1.0 * viewWidth/viewHeight;
double bitmapAspectRatio = 1.0 * options.outWidth/options.outHeight;
if (bitmapAspectRatio > viewAspectRatio)
reqHeight = (int) (viewWidth/bitmapAspectRatio);
else
reqWidth = (int) (viewHeight * bitmapAspectRatio);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
System.gc(); // TODO - remove explicit gc calls
return BitmapFactory.decodeFile(filePath, options);
}
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
答案 1 :(得分:1)
我正在使用Glide(https://bumptech.github.io/glide/)有效地加载大型位图。如果要从设备加载照片,Glide还会为您处理正确的旋转。
val myUri = ...
val neededHeight = 600
val neededWidth = 800
val bitmap = GlideApp
.with(context)
.asBitmap()
.load(myUri)
.override(neededWidth, neededHeight)
.submit()
.get()
答案 2 :(得分:0)
试试这个,只需将其添加到AndroidManifest.xml
<application
...
android:largeHeap="true">
<activity
android:name=".MainActivity"
...
答案 3 :(得分:-1)
图像很大。我建议缩小图像或使用毕加索库来更好地利用内存问题和图像缓存。