How can I save canvas of ImageView to a Bitmap? - android

I've got an ImageView, in its onDraw(canvas),
i tried:
canvas.drawBitmap(...);//draw an extremely large background 3264 * 2448 pixels
canvas.drawLine(...);//draw target
My question is, how can I save this canvas into a sth like png? Thanks!

From the question here:
Drawing on Canvas and save image
imgView.setDrawingCacheEnabled(true);
Bitmap b = imgView.getDrawingCache();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(getFileName());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
b.compress(CompressFormat.PNG, 95, fos);

You can save the view cache image to the disk as png.

Related

Can we save canvas as an Image to sd card in Android?

I am working with Canvas in Android Studio, have .png image on canvas and want to save it to sd card. Is it possible?
if yes then how?
thanks and regards.
This code may help you (Saving canvas to bitmap on Android)
Bitmap toDisk = null;
try {
// TODO: Get the size of the canvas, replace the 640, 480
toDisk = Bitmap.createBitmap(640,480,Bitmap.Config.ARGB_8888);
canvas.setBitmap(toDisk);
toDisk.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File("arun.jpg")));
} catch (Exception ex) {
}
You should have created Canvas with new Canvas(myBitmap);. So when you draw on the Canvas, it draws to your bitmap.
String fileName = Environment.getExternalStorageDirectory() + "/test.png";
OutputStream stream = new FileOutputStream(fileName);
/* Write bitmap to file using JPEG or PNG and 80% quality hint for JPEG. */
myBitmap.compress(CompressFormat.PNG, 80, stream);
stream.close();

Android apply custom sticker on image

I'm trying to fuond an image editor library that allow me to put a sticker on an image. I've found two libraries, one is Aviary , but I can't put my own stickers in it, then I've tried Android-image-edit but is very simple and it's not a library, it's an application.
Anyone knows some good libraries that allow me to do what I'm trying to do?
Thanks in advance.
I don't know a library, but if I understand you right, you want to add one Drawable onto an image?
You can do this yourself: (untested!)
public void putSticker(File file, Bitmap overlay) {
//Load bitmap from file:
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
bitmap = bitmap.copy(Bitmap.Config.RGB_565, true);
//Draw overlay:
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(overlay, 0, 0, paint);
//Save to file:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 40, bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
fos.write(bitmapdata);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Maybe there is a better way for loading and saving. But drawing is the interesting part for your question, anyway.
See http://developer.android.com/reference/android/graphics/Canvas.html for more drawBitmap() possibilities. (Offsets, Scaling, ...)
I don't know, if anyone's still looking for this, but this library can you in every possible way, to add a sticker.
https://github.com/wuapnjie/StickerView

Bitmap loses transparency when it's saved

i have a problem when i'm trying to save a bitmap to the external picture directory. When i use the Bitmap.compress function to save it, the bitmap loses its transparency and makes the background black. But when i pass the bitmap to a imageview and show it in the activity it looks fine and has transparency. Only when i try to save it, then transparency turns black.
I have to say, that im using two bitmaps and porterduff mode the draw a path on a bitmap and show only the picture in the drawn path, and all other pixels should be cut off or transparent.
So here's the function for creating a path bitmap:
private void createPathBitmap(RectF rect, Bitmap bitmap, Path path) {
RectF tmpRect = new RectF(rect);
Bitmap src = Bitmap.createBitmap(bitmap, (int) tmpRect.left, (int) tmpRect.top, (int) tmpRect.width(), (int) tmpRect.height());
Bitmap dst = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(dst);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(mDisplayDensity * SnippetLayer.PATH_DIAMETER);
path.offset(-rect.left, -rect.top);
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
RectF srcRect = new RectF(0, 0, rect.width(), rect.height());
canvas.drawBitmap(src, null, srcRect, paint);
BitmapManager.sBitmapSnippet = dst;
}
And here's the method for saving that bitmap to external storage:
SimpleDateFormat dateFormat = new SimpleDateFormat("HH_mm_ss_dd_MM_yyyy");
File snippetFile = new File(picDir, fileName+"_"+dateFormat.format(new Date())+".png");
try {
FileOutputStream fileOutputStream = new FileOutputStream(snippetFile);
BitmapManager.sBitmapSnippet.setHasAlpha(true);
BitmapManager.sBitmapSnippet.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The picture is shown only in the path, and the rest of the bounding box is black and not transparent.
I appreciate any help.
I'm using compress() method to write bitmap into output stream:
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
It is important to use PNG format. JPEG transforms my transparent background into black color.
I don't know why exactly does it lose transparency, but I had the same problem. All you have to do is to change
BitmapManager.sBitmapSnippet.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
to
BitmapManager.sBitmapSnippet.compress(Bitmap.CompressFormat.PNG, 0, fileOutputStream);.
This will compress the bitmap with full quality, but containing transparent regions.
Don't loose transparency by this small snippet
Here Problem is you save image in .JPEG so JPEG take black background as transparent so we will save in .PNG so definitely get transparent Image
private void saveImage(Bitmap data, View view) {
File createFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Magic PhotoShoot");
if (!createFolder.exists())
createFolder.mkdir();
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String strDate = sdf.format(c.getTime());
File saveImage = new File(createFolder, "Photoshoot_" + strDate + ".png");
try {
OutputStream outputStream = new FileOutputStream(saveImage);
data.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.flush();
outputStream.close();
Snackbar.make(view, "Saved to PhotoShoot successfully", Snackbar.LENGTH_SHORT).show();
isSave = true;
Glob.savedImage = saveImage.getAbsolutePath();
MediaStore.Images.Media.insertImage(getContentResolver(), saveImage.getAbsolutePath(), saveImage.getName(), saveImage.getName());
} catch (FileNotFoundException e) {
Snackbar.make(view, "File not found", Snackbar.LENGTH_SHORT).show();
e.printStackTrace();
} catch (IOException e) {
Snackbar.make(view, "Error while saving image", Snackbar.LENGTH_SHORT).show();
e.printStackTrace();
}
}
JPEG does not support transparency. JPEG's lossy compression also suffers from generation loss, where repeatedly decoding and re-encoding an image to save it
Use PNG extension file format for storing images in storage
In Kotlin:
Here is bitmap which is used for compression and saving into storage using file path
val file=File(outputImagePath)
var fout: OutputStream? = null
fout = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fout)
fout.flush()
fout.close()`
In Java:
Here is bitmap which is used for compression and saving into storage using file path
File imageFile = new File(outputImagePath);
OutputStream fout = null;
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
fout.flush();
fout.close();
You should use Bitmap.CompressFormat.PNG or Bitmap.CompressFormat.WEBP. If you want to get less size image. you should use Bitmap.CompressFormat.WEBP like me.

Android Bitmaps always saved with 72dpi

I'm making bitmap (that will be printed on paper, later) and using canvas to draw on it.
But after saving it always have 72 dpi resolution. I tried to use bitmap.setDensity(96);but it does not seems to work.
This is how I make bitmap and save it, nothing fancy
Bitmap outBitmap = Bitmap.createBitmap(378,559,Bitmap.Config.RGB_565);
OutputStream outStream = null;
File file = new File(Environment.getExternalStorageDirectory(),
"96dpiBitmap.png");
try {
outStream = new FileOutputStream(file);
outBitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
// doh
} catch (IOException e) {
// doh
}
So. How do I save bitmap with dpi > 72?
you have to create scaled bitmap from the original one for ex :
MyNewBitmap = Bitmap.createScaledBitmap(myOldOne,612,612,false);
where 612 width and 612 height the result will be image squared. i'm using this method to prevent instagram from scaling or cutting my image so its perfectly fit into instagram image cropping :).
anyway you have to find the proper way to scale your image to fit 72dpi. i guess 800x600 will do the trick. try to create new bitmap and scale the old one and then save the newBitmap.
good luck

How to save canvas drawing using SurfaceView as image?

How to save canvas drawing using SurfaceView as image not the view.
Try below code might help
Bitmap bitmap = Bitmap.createBitmap(mSurfaceView.getWidth(), mSurfaceView.getHeight(), Bitmap.Config.ARGB_8888);
mSurfaceView.draw(new Canvas(bitmap));
try {
OutputStream out = new BufferedOutputStream(new FileOutputStream(saved.png));
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (IOException e) {
Log.w(TAG, e);
}

Categories

Resources