Creating an empty bitmap and drawing though canvas in Android
This is probably simpler than you're thinking:
int w = WIDTH_PX, h = HEIGHT_PX;
Bitmap.Config conf = Bitmap.Config.ARGB_8888; // see other conf types
Bitmap bmp = Bitmap.createBitmap(w, h, conf); // this creates a MUTABLE bitmap
Canvas canvas = new Canvas(bmp);
// ready to draw on that bitmap through that canvas
Here's the official documentation on the topic: Custom Drawing
Creating a bitmap of a View that never gets drawn
Thanks to both @Rafael Toledo and @Roman_Donchenko, I figured out the issue. The problem was that my custom view was doing the drawing in the onDraw
method which doesn't get called. In my case, I simply needed to perform the drawing done in the onDraw
directly to the canvas and then used the bitmap passed to the canvas. My code ended up being:
public Bitmap getBitmapFromCircleView(CircleView v)
{
Bitmap bitmap = Bitmap.createBitmap(v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
v.drawToCanvas(canvas); //Method in the custom CircleView class, posted below
return bitmap;
}
public class CircleView extends View
{
... //Constructors
public Canvas drawToCanvas(Canvas canvas)
{
canvas.drawColor(0x00000000);
if(m_lineWidthPx == 0) //Previously set
return null;
int width = getLayoutParams().width;
int height = getLayoutParams().height;
float centerX = height / 2.f;
float centerY = height / 2.f;
float radius = width / 2.f - (m_lineWidthPx) / 2.f;
m_paint.setStrokeWidth(m_lineWidthPx);
m_paint.setStyle(Paint.Style.STROKE);
m_paint.setAntiAlias(true);
canvas.drawCircle(centerX, centerY, radius, m_paint);
return canvas;
}
@Override protected void onDraw(Canvas c)
{
... //Code here remained unchanged
}
}
Android: drawing on the Canvas and View (without Bitmap)
I've found non-trivial solution. I've inited the view by the constructor with 1 parameter. And then I inserted the custom view in the layout and called invalidate() when I needed it.
how do I create a huge, white bitmap with Canvas?
Naturally, you are limited by memory when you want to create huge bitmaps, but you have enough memory to create quite big bitmaps. For example, a 1024*1024 ARGB_8888 bitmap will need roughly 4 MB of memory, which is not a problem if your app is frugal with memory in general. The normal heap size for an Android app is usually between 16-32 MB depending on Android version, just to give you a feeling for what you have to play with.
You say you make a copy of large bitmap, and that might be your main problem. There's no need to make a copy of a large bitmap, you need only one. Here's a sample project that creates a large (1024*1024) white bitmap and draws a View in your app in the middle of it, and then writes the result to a 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 main 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'll get a bitmap somewhere like /mnt/sdcard/Pictures/big-white-image-with-view.png
that looks something like this:
Android creating a circle bitmap without drawing it on canvas
You can easily get a bitmap object using Bitmap static method (Bitmap.create) and then use that object to draw anything on it by instantiating a canvas object with bitmapObject
.
your code should look something like this:
Bitmap bitmap = Bitmap.create(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
//draw on your canvas.
Related Topics
Padding Between Actionbar's Home Icon and Title
Android: Create Circular Image with Picasso
How to Notify Users About an Android App Update
Assign Width to Half Available Screen Width Declaratively
How to Update Notification with Remoteviews
Android - Hide All Shown Toast Messages
Justify Text in an Android App Using a Webview But Presenting a Textview-Like Interface
Firebase Cloud Messaging - How to Validate Tokens
Using Tesseract for Handwriting Recognition
Login Error: There Is an Error in Logging You into This Application. Please Try Again Later
How to Add Bulleted List to Android Application
How to Use Isineditmode() to See Layout with Custom View in the Editor
Cordova Plugin Development - Adding Aar
Emulator Appearing Offline on M1 MAC After the Last Update of Arm64-V8A