Using BitmapFactory.Options(); - android

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

Related

CreateScaledBitmap returns a blank image in android

I have been trying to follow this answer https://stackoverflow.com/a/8527745/1352702
, to create a scaled bitmap instead of just drawing a bitmap on the canvas, to solve some memory issues.
Here is my code,
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
options.inInputShareable = true;
options.inSampleSize = 8;
Bitmap s000 = BitmapFactory.decodeResource(getResources(), getResources().getIdentifier("zoo" + i, "drawable", getPackageName()));
int X = c.getWidth()/2 - s000.getWidth()/2 ;
int Y = c.getHeight()/2 - s000.getHeight()/2 ;
Bitmap.createScaledBitmap(s000, s000.getWidth(), s000.getHeight(), true);
But it just creates a blank screen.
Also how to pass the position parameters of the image (X and Y respectively) in the createScaledBitmap method ?
For the record, I had the same issue when trying to resize certain hi-resolution grayscale PNGs : they were properly loaded by BitmapFactory.decodeResource, then Bitmap.createScaledBitmap turned them into black pictures.
Turns out that, on API 26+, Android doesn't know how to handle bitmaps whose ColorSpace is not properly detected ("Unknown"), and messes up the resizing.
The working solution for my app was to define a preferred ColorSpace at load time :
BitmapFactory.Options options = new BitmapFactory.Options();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
options.inPreferredColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
bitmap = BitmapFactory.decodeXXX(<whatever method you fancy>, options);

How to efficiently decode a image knowing only its path

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);

After capturing a layout screenshot, ImageView is transparent

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()

Differences between BitmapFactory.decodeResource and BitmapFactory.decodeStream

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);

Any way to improve speed of BitmapFactory.decodeStream()?

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);

Categories

Resources