I've got an if-else scenario where the if-path uses this code:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inPurgeable = true;
options.inInputShareable = true;
bitmap = BitmapFactory.decodeResource(getResources(), resourceId, options);
And the else-path uses this code:
InputStream is = getContentResolver().openInputStream(Uri.fromFile(file));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inPurgeable = true;
options.inInputShareable = true;
bitmap = BitmapFactory.decodeStream(is, null, options);
Now to me, reading the short description from the API, testing and Googling I can't quite figure out the difference, but there seems to be a suble one.
The first piece of code scales to fit the width of the screen when applied to a ImageView (within a RelativeLayout, within a ScrollView). The second piece of code does not, which is my problem. It seems to loose it's aspect ratio somehow as well, because if I apply:
imageView.setAdjustViewBounds(true);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
It manages to fit it to the width, but messes up the height (making it shorter than it should be). Any input would be greatly appreciated!
(I've already tried to change the first piece of code to see if I had messed something else up, but this rewrite of the if-path gave the same error:)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inPurgeable = true;
options.inInputShareable = true;
bitmap= BitmapFactory.decodeStream(getResources().openRawResource(resourceId), null, options);
Related
So i'm creating bitmap, using this code:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inMutable = true;
return BitmapFactory.decodeFile(photoPath, options);
My problem is, why is it taking so much time creating it on some mobile ?
is there any way to create bitmap without wasting a lot of time waiting ?
Does any guys meet this issue? Any help would be greatly appreciated.
1) Use a scaled down version of image so that you can avoid memory as well as execution time wastage
2) Try processing the bitmaps asynchronously.
You can refer to http://developer.android.com/training/displaying-bitmaps/index.html
Try Below Code Snippet:
public static Bitmap decodeFile(String photoPath){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photoPath, options);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inPreferQualityOverSpeed = true;
return BitmapFactory.decodeFile(photoPath, options);
}
I have taken and modified some code used to get a high quality anti-aliased small version of a larger (500x500) bitmap image. Apparently using a Matrix produces higher quality than employing createScaledBitmap(). The results were not very impressive.. and I suspected that perhaps I had made a mistake, in particularl I was unsure as to whether the options thing was actually being employed. So I changed the inSampleSize = 1; to inSampleSize = 50; expecting to see a dramatic drop in quality, but there was no change. So now I suspect options is being ignored. Can this code be rescued?
I was hoping to perhaps find some version of createBitmap which took bith a bitmap and an options argument, but could find none.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferQualityOverSpeed = true;
options.inJustDecodeBounds = false;
options.inDither = false;
options.inSampleSize = 1;
options.inScaled = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bmpSource = BitmapFactory.decodeResource(getResources(), R.drawable.bigicon);
Matrix matrix = new Matrix();
matrix.postScale(.1f,.1f);
Bitmap scaledBitmap = Bitmap.createBitmap(bmpSource, 0, 0, bmpSource.getWidth(), bmpSource.getHeight(), matrix, true);
well you should actually provide it as parameter. Change
Bitmap bmpSource = BitmapFactory.decodeResource(getResources(), R.drawable.bigicon);
with
Bitmap bmpSource = BitmapFactory.decodeResource(getResources(), R.drawable.bigicon, options);
here the documentation
Take a look of this Creating a scaled bitmap with createScaledBitmap in Android
This too: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
I'm creating my own gallery using ViewPager, which is 'connected' to ArrayList holding paths of images to display.
So far, I use:
Bitmap bitmap = BitmapFactory.decodeFile(path);
imageView.setImageBitmap(bitmap);
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
It's working, but the pictures are pretty big and I unnecessarily decode whole picture, because it's scaled down later to fit layout. It is slow and a crash with OutOfMemoryError happens sometimes, when I scroll fast.
So the question is:
How can I efficiently decode an image so it fits 100% with ImageView.ScaleType.CENTER_INSIDE knowing only its path?
Do not decode it directy. use inJustDecodeBounds = true from BitmapFactory.Options, to load only width and height from the Bitmap. Then you can calcuate the inSampleSize to scale your Bitmap
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
decodeFile will return null and options will contains width and height. Then you calculate the inSampleSize and:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = myInsampleSize;
Bitmap output = BitmapFactory.decodeFile(path, options);
I have a problem in Android screen capture. The captured image is transparent while the original image is solid JPEG file which is not transparent!
I tested in on many devices with different OS version and problem persists on all phones.
Here is my code for screen capture and also the final output
Code:
final Bitmap rawBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(rawBitmap);
rendererView.layout(0, 0, width, height);
rendererView.draw(canvas);
rawBitmap.compress(CompressFormat.PNG, 100, new FileOutputStream("/sdcard/test" + System.currentTimeMillis() + ".png"));
Result:
The problem was solved. When loading image source to ImageView, I used wrong setting for BitmapFactory Options.
The Code ( Before And After ):
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
//options.inPreferredConfig = Config.ARGB_4444; //WRONG
options.inPreferredConfig = Config.ARGB_8888; //CORRECT
bitmap = BitmapFactory.decodeFile(result.filePath(), options);
Thanks you all.
I would try Bitmap.Config.RGB_565 in createBitmap()
Obviously this is an expensive/time-consuming operation. Any way to improve this?
Bitmap bm = BitmapFactory.decodeStream((InputStream) new URL(
someUrl).getContent());
I'm guessing there's really no way to avoid this relatively intense operation, but wanted to see if anyone had any tweaks they could recommend (aside from caching the actual bitmap, which for whatever reasons simply isn't relevant here)
If you don't need the full resolution you can have it only read ever nth pixel, where n is a power of 2. You do this by setting inSampleSize on an Options object which you pass to BitmapFactory.decodeFile. You can find the sample size by just reading the meta-data from the file in a first pass by setting inJustDecodeBounds on the Options object. Aside from that - no, I don't think there's an easy way to make to go any faster than it already does.
Edit, example:
Options opts = new Options();
// Get bitmap dimensions before reading...
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, opts);
int width = opts.outWidth;
int height = opts.outHeight;
int largerSide = Math.max(width, height);
opts.inJustDecodeBounds = false; // This time it's for real!
int sampleSize = ??; // Calculate your sampleSize here
opts.inSampleSize = sampleSize;
Bitmap bmp = BitmapFactory.decodeFile(path, opts);