How to create a huge white raster map with Canvas?

I'm trying to figure out how I can use Canvas to draw small graphics (it really doesn't matter what it is) onto a large white surface. The problem is that if I start with a large empty bitmap, when I make a volatile copy of it using ARGB_8888, Android will run out of memory right away. I am curious if I missed something, or if it is actually impossible to assemble small graphics on a large white surface and save it as PNG or JPG due to memory limitations in Android.

+4
source share
1 answer

Naturally, you are limited by memory when you want to create huge bitmaps, but you have enough memory to create quite large bitmaps. For example, a 1024 * 1024 bitmap ARGB_8888 will require approximately 4 MB of memory, which is not a problem if your application is economical with memory in general. The typical heap size for an Android app is usually between 16 and 32 MB depending on the version of Android to give you a feel for what you have to play with.

You say you are making a copy of a large bitmap, and this may be your main problem. There is no need to make a copy of a large bitmap, you only need one. Here is an example project that creates a large (1024 * 1024) white bitmap and draws a view in your application in the middle, and then writes the result to PNG:

package com.example.android; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Canvas; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.View; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class WhitePngActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViewById(R.id.draw_to_bitmap).setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Bitmap largeWhiteBitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888); // Make a canvas with which we can draw to the bitmap Canvas canvas = new Canvas(largeWhiteBitmap); // Fill with white canvas.drawColor(0xffffffff); // Draw the view to the middle of the big white bitmap. In this // case, it will be the button, but you can draw any View in // your view hierarchy to the bitmap like this. And of course // you can position the View anywhere you want canvas.save(); canvas.translate( largeWhiteBitmap.getWidth() / 2 - view.getWidth() / 2, largeWhiteBitmap.getHeight() / 2 - view.getHeight() / 2); view.draw(canvas); canvas.restore(); // Write the file (don't forget android.permission.WRITE_EXTERNAL_STORAGE) File pictureDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); File pngFile = new File(pictureDir, "big-white-image-with-view.png"); try { largeWhiteBitmap.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(pngFile)); } catch (FileNotFoundException e) { Log.e("WhitePngActivity", "Could not write " + pngFile, e); } // Immediately release the bitmap memory to avoid OutOfMemory exception largeWhiteBitmap.recycle(); } }); } } 

Together with this basic layout:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/draw_to_bitmap" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Click to draw to bitmap" /> </LinearLayout> 

You will get a bitmap somewhere like /mnt/sdcard/Pictures/big-white-image-with-view.png , which looks something like this:

enter image description here

+6
source

Source: https://habr.com/ru/post/1396424/


All Articles