Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is a way to work around, but this will take a little bit longer than scaling bitmap directly. <br></p> <ol> <li>First, decode the original bitmap as original size </li> <li>Split into small bitmaps, in this case is 10 bitmaps with the width = originalWidth/10 and height = originalHeight. And width each bitmap of those, scale to the size of target/10 then save into file. (we do this one by one and release memory after each step.) </li> <li>Release the original bitmap </li> <li>Create a new bitmap with the target size. </li> <li>Decode each bitmap saved in file before and draw onto the new bitmap. Store the new scaled bitmap for future usage.</li> </ol> <p>The method is something like this: <br></p> <pre><code>public Bitmap newResizedPixmapWorkAround(Bitmap.Config format, double width, double height) { int[] pids = { android.os.Process.myPid() }; MemoryInfo myMemInfo = mAM.getProcessMemoryInfo(pids)[0]; Log.e(TAG, "dalvikPss (beginning) = " + myMemInfo.dalvikPss); Config config = null; if (format == Bitmap.Config.RGB_565) { config = Config.RGB_565; } else if (format == Bitmap.Config.ARGB_4444) { config = Config.ARGB_4444; } else { config = Config.ARGB_8888; } Options options = new Options(); options.inPreferredConfig = config; options.inPurgeable = true; options.inInputShareable = true; options.inDither = false; InputStream in = null; Bitmap bitmap = null; try { // OPEN FILE INTO INPUTSTREAM String path = Environment.getExternalStorageDirectory() .getAbsolutePath(); path += "/sprites.png"; File file = new File(path); in = new FileInputStream(file); // DECODE INPUTSTREAM bitmap = BitmapFactory.decodeStream(in, null, options); if (bitmap == null) { Log.e(TAG, "bitmap == null"); } } catch (IOException e) { Log.e(TAG, "IOException " + e.getMessage()); } finally { if (in != null) { try { in.close(); } catch (IOException e) { } } } if (bitmap.getConfig() == Config.RGB_565) { format = Bitmap.Config.RGB_565; } else if (bitmap.getConfig() == Config.ARGB_4444) { format = Bitmap.Config.ARGB_4444; } else { format = Bitmap.Config.ARGB_8888; } myMemInfo = mAM.getProcessMemoryInfo(pids)[0]; Log.e(TAG, "dalvikPss (before separating) = " + myMemInfo.dalvikPss); // Create 10 small bitmaps and store into files. // After that load each of them and append to a large bitmap int desSpriteWidth = (int) (width + 0.5) / 10; int desSpriteAppend = (int) (width + 0.5) % 10; int desSpriteHeight = (int) (height + 0.5); int srcSpriteWidth = bitmap.getWidth() / 10; int srcSpriteHeight = bitmap.getHeight(); Rect srcRect = new Rect(0, 0, srcSpriteWidth, srcSpriteHeight); Rect desRect = new Rect(0, 0, desSpriteWidth, desSpriteHeight); String pathPrefix = Environment.getExternalStorageDirectory() .getAbsolutePath() + "/sprites"; for (int i = 0; i &lt; 10; i++) { Bitmap sprite; if (i &lt; 9) { sprite = Bitmap.createBitmap(desSpriteWidth, desSpriteHeight, format); srcRect.left = i * srcSpriteWidth; srcRect.right = (i + 1) * srcSpriteWidth; } else { // last part sprite = Bitmap.createBitmap(desSpriteWidth + desSpriteAppend, desSpriteHeight, format); desRect.right = desSpriteWidth + desSpriteAppend; srcRect.left = i * srcSpriteWidth; srcRect.right = bitmap.getWidth(); } Canvas canvas = new Canvas(sprite); // NOTE: if using this drawBitmap method of canvas do not result // good quality scaled image, you can try create tile image with the // same size original then use Bitmap.createScaledBitmap() canvas.drawBitmap(bitmap, srcRect, desRect, null); String path = pathPrefix + i + ".png"; File file = new File(path); try { if (file.exists()) { file.delete(); } file.createNewFile(); FileOutputStream fos = new FileOutputStream(file); sprite.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.flush(); fos.close(); sprite.recycle(); } catch (FileNotFoundException e) { Log.e(TAG, "FileNotFoundException at tile " + i + " " + e.getMessage()); } catch (IOException e) { Log.e(TAG, "IOException at tile " + i + " " + e.getMessage()); } } bitmap.recycle(); bitmap = Bitmap.createBitmap((int) (width + 0.5f), (int) (height + 0.5f), format); Canvas canvas = new Canvas(bitmap); desRect = new Rect(0, 0, 0, bitmap.getHeight()); for (int i = 0; i &lt; 10; i++) { String path = pathPrefix + i + ".png"; File file = new File(path); try { FileInputStream fis = new FileInputStream(file); // DECODE INPUTSTREAM Bitmap sprite = BitmapFactory.decodeStream(fis, null, options); desRect.left = desRect.right; desRect.right = desRect.left + sprite.getWidth(); canvas.drawBitmap(sprite, null, desRect, null); sprite.recycle(); } catch (IOException e) { Log.e(TAG, "IOException at tile " + i + " " + e.getMessage()); } } myMemInfo = mAM.getProcessMemoryInfo(pids)[0]; Log.e(TAG, "dalvikPss (before scaling) = " + myMemInfo.dalvikPss); // THIS IS WHERE THE OOM HAPPENS return bitmap; } </code></pre> <p>I have tested with my phone and it run without OOM when scaling to 1.5 (which the original method will run into OOM)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload