Android - store image on a temp file cross-activity - android

In the app I am developing, I have an activity in which I show two ImageViews made of two bitmaps, ca.bm and ca.tempBm respectively. It works fine on my device but produces OutOfMemoryError on some devices when trying to copy the original bitmap to the bitmap I will modify later:
ca.tempBm = Bitmap.createBitmap(ca.bm); // out of memory error
I would like to create a temp file instead to hold the original image and work with a single bitmap, but the temp file must be preserved when changing from the Camera Activity to the next activity and should be destroyed only when the second activity does.
How can I achieve this?

You can write a Bitmap to the cache directory with:
FileOutputStream outStream = new FileOutputStream(new File(getCacheDir(), "tempBMP"));
myBitmap.compress(Bitmap.CompressFormat.JPEG, 75, outStream);
outStream.close();
And read back in with:
Bitmap myBitmap = BitmapFactory.decodeFile(bitmapPath.getAbsolutePath());
But you might be better off just saving memory by creating a smaller Bitmap, drawing the larger Bitmap to the smaller Bitmap's canvas, then passing around the smaller Bitmap between Activities.

Related

Issues with merging two bitmaps

I'm trying to add one bitmap (png file) on top of another and then save it to the device. Everything works fine except for the first part.
Bits of my code:
1 converting loaded file to bitmap
loadedBitmap = e.target.content as Bitmap;
clonedBitmap = new Bitmap(loadedBitmap.bitmapData.clone());
bitmapData = new BitmapData(e.target.content.width, e.target.content.height);
bitmapData.draw(clonedBitmap);
2 second Bitmap generated within the app
genBitmapData = new BitmapData(bgWidth, bgHeight, false);
genBitmap = new Bitmap(genBitmapData);
3 adding clonedBitmap (external file) to the bitmapdata
var positionMatrix : Matrix = new Matrix(1,0,0,1,0,0);
genBitmapData.draw(clonedBitmap, positionMatrix);
The problem with the step three is that the loaded file clonedBitmap end up being under the bitmap generated by the app upon saving it to the device's storage. When I reverse the order:
bitmapData.draw(genBitmap, positionMatrix);
Only the generated bitmap is displayed/visible while the loaded bitmap isn't visible at all upon saving the file. What I'd like to achieve is to have clonedBitmap (external png file) to be on top of the genBitmap and saved withing a BitmapData object, so I could be able to save it to my device.
I'd be grateful for any tips.
When you draw a bitmap over a bitmap, you need the bitmap being overlayed to be transparent somewhere, otherwise all the lower bitmap's pixels would be overwritten with the upper layer. Therefore, create those bitmaps with alpha channel (transparency=true), make sure the upper layer bitmap is also transparent after you draw a something on it (at least somewhere), then draw first lower layer then upper layer on a single BitmapData object.
Note that since you don't transform any bitmaps, you'd better use BitmapData.copyPixels() method.
It turns out the code works fine. I just overlooked and placed it in the wrong function, which caused the issue.

Decreasing File Size of Image From ImageView

I use the following code to obtain a bitmap from an ImageView. This image is not saved anywhere else on my device. I want to upload this image into an online mysqli database. However, to do so I need to decrease the size of the file first. I found a lot of links about this, however they all require the file to be saved on the device and then use FileOutputStream. I am looking for a way to reduce the file size so that it can be comfortably transferred using the Volley API ( i am currently receiving either run out of memory exceptions or broken pipe errors). Hence I am looking for a way to modify this code to be able to significantly decrease the file size, whilst still maintaining a quality which can be comfortably shown on a mobile device. The original image is taken straight from the camera hence the size is quite large. Here is my code:
ImageView pic_holder = (ImageView) findViewById(R.id.picturedisplay);
Bitmap bitmap = ((BitmapDrawable)pic_holder.getDrawable()).getBitmap();
ByteArrayOutputStream stream=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] image=stream.toByteArray();
String img_str = Base64.encodeToString(image, 0);
I would like to decrease the size of the img_str which is passed to my Volley method.

Android saving webview to gallery, intermediate bitmap is too big

I am trying to write a method in android to save the whole webview as an image as following:
bitmap = Bitmap.createBitmap(webView.getWidth(),
Math.round(webView.getContentHeight() * webView.getScale()), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
webView.draw(canvas);
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, JPEG_COMPRESSION, out);
However, the bitmap is too big (more than 100 MB) and takes too much memory. Does anyone know any better method to keep the memory usage low?
The problem is the WebView is small, and the generated JPEG file is small but the intermediate Bitmap which is not used any more in other places is huge.
Set JPEG_COMPRESSION = 0-100 as it is a quality paramater of bitmap 0 meaning compress for small size, 100 meaning compress for max quality.
You can also set bitmap height and width using
BitmapFactory.Options bop
bop.outWidth
bop.outHeight

in-memory and saved to file bitmaps are different for same byte[]

I have a byte array. I then create a Bitmap object from it like this and display it in an ImageView:
Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
ByteBuffer buffer = ByteBuffer.wrap(bytes);
image.copyPixelsFromBuffer(buffer);
...
ImageView imgView = (ImageView) findViewById(R.id.image);
imgView.setImageBitmap(image);
I then create a file and store this byte array as an image
FileOutputStream fOut = new FileOutputStream(file);
image.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
When I open this file in Gallery, it looks different than the one in the ImageView. I tried to write the bytes directly to file, as opposed to the Bitmap, but then I was not able to open the image at all.
ImageView:
Gallery:
I thought that Bitmap.CompressFormat.PNG, endured no compression. What am I missing here?
EDIT:
I don't know if it matters, but the original bytes array comes from encrypting another byte array that came from an original picture. I loaded an image from disk, created a byte array, modified it, and then tried the above with it.
It's probably because you view your image with different background colors in your app and in Gallery. Since you use Bitmap.Config.ARGB_8888 and effectively feed it random data, some pixels will be transparent in the resulting image, and the color of the background will "shine through" when you view the image. If you make the background color of your app black, the image will probably look like it does in Gallery.

Android - Load and save bitmap without increase destination file size

I have a problem in saving images in my app.
The process is simple:
1 - I read the image into a bitmap for display
2 - Save the bitmap as a new file
At this point, I do not understand why the final file has a size much larger than the original image. For example, a 170 kb image is saved in a new file 1 mb.
I know the difference in the management of compression between PNG and JPG, but I expect that if I read a PNG file, and save it in the same format, the size remains the same.
Thank you all for the help.
Edit
This is my code for saving method:
Bitmap resized = Bitmap.createScaledBitmap(original, generateWidth, generateHeight, false);
FileOutputStream out = new FileOutputStream(tempResizedFile.getPath());
resized.compress(generateType.CompressFormat(),
qualityBar.getProgress(), out);
out.close();

Categories

Resources