I capture image by default camera software and I get saved my image into some directory to local memory. My question is, is there any way how to make this picture smaller? I will need to send it via internet connection to server, that's why it has to be VGA on maximum. I know there is way to write my own photo part of an app, but I thinks it is nice to use default and then some method for making the picture smaller. I just haven't figured out, how. Any ideas?
Thanks
For example:
InputStream is = new FileInputStream(new File(Environment.getExternalStorageDirectory(), "image.tmp"););
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; //subsampling
int compress = 75;
BitmapFactory.decodeStream(is, null, options).compress(CompressFormat.JPEG, compress, new FileOutputStream(file));
It's dirty example. Use try catch, null check etc.
Related
So, I'm updating an old e-book reader. The problem I'm facing is the size of the bitmaps (the pages). The way it works is: the app downloads a file, extract it, decode it with our DRM then I can access all pages. The thing is, each page its a 35mb bitmap.
I need to reduce this by a lot. I can't convert the file to any other format.
I tried this:
byte[] rawBytes = intToByteArray(b.getByteCount());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bit = BitmapFactory.decodeByteArray(rawBytes, 0,rawBytes.length, options);
But the Bitmap keeps returning null, and for what I gathered its when the Bitmap facorty can't decode the bitmap.
So, there is any other way to reduce the impact of this big bitmaps ?
It seems the answers I searched online (including stackoverflow.com) get the image file id through gallery selection.
I have created my own file explorer.
Then how to do that?
I can create my own small size image; but I think it would be faster if we can make use of an exisiting thumbnail; and if it does not exist, I would prefer to create a thumbnail that is saved for later use.
[Update:]
OK, thanks for advice. So I will not create a thumbnail in the device, to avoid to use too much space.
Then is is better to do two steps:
Step 1: look for an exisiting thumbnail for the image file if it exists.
Step 2: if no thumbnail exists, then create my own small size bitmap (not save the it).
Then how to do Step 1, if I do not use the Gallery intent?
[Update 2:]
I also want to get the thumbnail of a video file.
I can use MediaMetadataRetriever to get a frame at any point of time, and rescale the image to a thumbnail. But I find it is very slow: I have 4 video files in the folder, and I can sense the delay.
So I think the better way to retrieve an existing thumbnail.
If I only know the file path and file name, how can I get it?
I think this question is the same as my original one, just it has more sense to do so.
You shouldn't be using specific files for tumbnail, especially not creating tumbnails. What if the user has a lot of images and you store a tumbnail of each picture which gets viewed in your explorer. That would generated a whole lot of duplicated and unwanted data. The calculations from resizing the images each time overweighs the amount of data that would need to be stored.
I would suggest you have a default icon on images in the explorer and then resizing the images in a diffrent thread, replacing your default tumbnail as they are resized.
You could downsize the existing images on the fly:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image_path, opts);
int width = opts.outWidth;
int height = opts.outHeight;
then
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
opts.inDither = true;
opts.inJustDecodeBounds = false;
opts.inSampleSize = (int)Math.pow(2.0,Math.floor(Math.log(scale_factor)/Math.log(2)));//for example double scale_factor=(double)width/desired_dimension;
and finally:
Bitmap bm = BitmapFactory.decodeFile(image_path,opts);
You could load in a separate thread ranges of existing files and update only those ones when needed.
You can use ThumbnailUtils. Look up the this utility method. Probably fits your need without much hassles. Creating duplicate downsized images is a bad design as that it will end up unnecessary data.
Bitmap resizedImage = ThumbnailUtils.extractThumbnail(rescaledImage, imagePixel, imagePixel);
I am currently building this Android application, where I will be taking a screenshot of a "TableLayout" and then emailing it as an attachment. Here is the part of the code which takes the screenshot.
However, when I try to attach the file, using the following code, it says that "File Size Too Large for Attachment". Can anyone suggest any other measures that I can take, apart from Bitmap.Compress, in order to make my file size even smaller? Thanks in advance!
private void getScreen()
{
View content = findViewById(R.id.TransactionLog);
content.setDrawingCacheEnabled(true);
content.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(content.getDrawingCache());
content.setDrawingCacheEnabled(false); // clear drawing cache
File file = new File(Environment.getExternalStorageDirectory() +
File.separator + "whatever2.png");
try
{
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 0, ostream);
ostream.flush();
ostream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
Try using Bitmap.createScaledBitmap:
public static Bitmap createScaledBitmap (Bitmap src, int dstWidth, int
dstHeight, boolean filter)
Since: API Level 1
Creates a new bitmap, scaled from an existing bitmap.
Parameters
src - The source bitmap.
dstWidth - The new bitmap's desired width.
dstHeight - The new bitmap's desired height.
filter - true if the source should be filtered.
FYI, the quality parameter passed to compress does not affect the file size when you are using CompressFormat.PNG. Try using CompressFormat.JPEG instead, then try different quality values.
Alternatively, try this:
http://thinkandroid.wordpress.com/2009/12/25/resizing-a-bitmap/
Have you tried use a higher value for the quality parameter? (currently you're using 0 and it could go up to 100).
I suggest trying 80.
boolean success = bitmap.compress(CompressFormat.PNG, 80, ostream);
Don't forget to test if it was successful (log the return value of that method).
You can also try to use another format (jpeg?).
To make things simpler, I suggest you to try to save it to the sdcard first and check if the size is something you'd be expecting. You might have some problem on the code that sends the email or it might not let you send large attachments.
How big is your image? An image made from an app, saved as a png, assuming its not a screenshot of a 'picture', should be pretty small. FAR smaller than what email should be able to accept, unless there's an arbitrarily small attachment size.
If what's in your table is an image, or has quite a bit of variance, you might consider jpeg instead of png. Otherwise, my guess is something else is going on.
I am working on a file manager kind of application in android in which i want to create thumbnails of the images.Thumbnails are getting created but the application often force closes giving out Out Of Memory Exception...
i tried out following code
icon.setImageURI(Uri.parse(path));
icon.setScaleType(ScaleType.FIT_XY);
icon.setLayoutParams(new LinearLayout.LayoutParams(30,30));
addView(icon);
Make sure that when you load the images you specify a sample rate to BitmapFactory.Options. This will keep your bitmaps from getting too big:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 4;
... use a BitmapFactory method, passing opts ...
I did like this it worked
Bitmap imagethumbnail=BitmapFactory.decodeFile(path); //complete file path
imagethumbnail=Bitmap.createScaledBitmap(imagethumbnail, 40, 40, true);
In Android, how do you display an image (of any size) from the SD card, without getting an out of memory error?
Is it necessary to put the image in the Media Store first?
A pseudo-code example would be greatly appreciated. Extra points if the displayed image is as big as the memory level of the device allows.
Edit: this question has actually been already answered at Strange out of memory issue while loading an image to a Bitmap object (the two highest voted answers). It does also use the inSampleSize option, but with a small method to automatically get the appropriate value.
My original answer:
The inSampleSize of the BitmapFactory.Options class can solve your issue (http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize). It works by making a bitmap with the resulting width and height 1/inSampleSize than the original, thus reducing memory consumption (by inSampleSize^2?). You should read the doc before using it.
Example:
BitmapFactory.Options options = new BitmapFactory.Options();
// will results in a much smaller image than the original
options.inSampleSize = 8;
// don't ever use a path to /sdcard like this, but I'm sure you have a sane way to do that
// in this case nebulae.jpg is a 19MB 8000x3874px image
final Bitmap b = BitmapFactory.decodeFile("/sdcard/nebulae.jpg", options);
final ImageView iv = (ImageView)findViewById(R.id.image_id);
iv.setImageBitmap(b);
Log.d("ExampleImage", "decoded bitmap dimensions:" + b.getWidth() + "x" + b.getHeight()); // 1000x485
However here it will only work for images up to, I guess, inSampleSize^2 times the size of the allowed memory and will reduce the quality of small images.
The trick would be to find the appropriate inSampleSize.
I'm displaying any sized images using code:
ImageView imageView=new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setAdjustViewBounds(true);
FileInputStream fis=new FileInputStream(file);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize=2; //try to decrease decoded image
options.inPurgeable=true; //if necessary purge pixels into disk
options.inScaled=true; //scale down image to actual device density
Bitmap bm=BitmapFactory.decodeStream(is, null, options);
imageView.setImageBitmap(bm);
fis.close();
For example:
yourImgView.setImageBitmap(BitmapFactory.decodeFile("/sdcard/1.jpg"));
http://www.developer.com/ws/other/article.php/3748281/Working-with-Images-in-Googles-Android.htm covers all you'll ever need to know on the subject of images, including getting them from an SD card. You'll notice the code to do so there, copied below:
try {
FileOutputStream fos = super.openFileOutput("output.jpg",
MODE_WORLD_READABLE);
mBitmap.compress(CompressFormat.JPEG, 75, fos);
fos.flush();
fos.close();
} catch (Exception e) {
Log.e("MyLog", e.toString());
}