Android draw image with width 1029 * height 1029 pixel - android

In my Android application, I need an image with size of width 1029 * height 1029 pixel (image center crop is allowed) . The original image width and height is above than 1029 pixels.
I have tried the following things.
I have placed the image in a image view and capture the bitmap I got the following exception.
Bitmap too large to be uploaded into a texture (2322x4128, max=4096x4096)
This is the layout design of image view.
<ImageView
android:id="#+id/iv_try1"
android:layout_width="425dp"
android:layout_height="425dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:scaleType="centerCrop"
android:contentDescription="#string/icd" />
( I am not sure 425dp gives 1029 pixels, just a try).
I used the following code to capture the bitmap from image view.
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
// resultant bitmap is save into save in SDcard.
How can I get an image with width 1029 * height 1029 pixel resolution as bitmap? Thanks in advance.

as the exceptions states your bitmap is too large. The height exceed the maximum value. What you can do is to downscale the bitmap. The first step would be to load only the meta-info of your bitmap with
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decode*(..., o);
setting inJustDecodeBounds = true, will make the decode* method return a null Bitmap, but the BitmapFactory.Options will contain the width/height of the bitmap in pixels. Knowing those two, you can calculate the value of inSampleSize that you need to scale the bitmap to with/height close to your constraint (1029 px). From the documentation of inSampleSize
If set to a value > 1, requests the decoder to subsample the original
image, returning a smaller image to save memory. The sample size is
the number of pixels in either dimension that correspond to a single
pixel in the decoded bitmap. For example, inSampleSize == 4 returns an
image that is 1/4 the width/height of the original, and 1/16 the
number of pixels. Any value <= 1 is treated the same as 1. Note: the
decoder uses a final value based on powers of 2, any other value will
be rounded down to the nearest power of 2.

Related

Why does BitmapFactory scale down my image by a factor of 1.333 instead of 2?

I have a PNG image file with 2236x971px dimensions as a resource.
I want to scale it down by a factor of two (to its half). However, when i use this code:
BitmapFactory.Options bo = new BitmapFactory.Options();
bo.inSampleSize = 2;
Bitmap decodedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image, bo);
the decodedBitmap.getWidth() and decodedBitmap.getHeight() show width: 1677, height:728 → Only 25% reduction in size instead of expected 50%. Why is that so?
I am running the code on API 19.
The reason is that, your resource gets loaded according to your screen metrics. Put your image in the drawable-nodpi Folder or open an input stream to your resource and decode that input stream.

Crop image from byte array

My app let the user take a picture with the camera and return a byte array containing the image data (jpeg at the moment but can be modified).
If we know the width and height of the picture, is it possible to use
BitmapFactory.decodeByteArray(data, offset, length)
To decode the picture from specified offset to get a squared picture ?
The image is in high res (portrait) and I only need the squared bottom of this picture still in high res for image processing.
x offset = 0
y offset = height - width
width = width
height = width
I have seen this answer but I still was wondering if this was possible. I could compress image data with another format if needed
My guess was to compute the number of bytes used to store n rows of pixels (using known dimensions), where n = maxRows - pictureWidth
and then start from computed offset
First decode to small size
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inSampleSize = 4; //inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels
BitmapFactory.decodeByteArray(data, offset, length, opt)
ANd Then
bitMap1 = Bitmap.createScaledBitmap(bitMap, width, height, true);
try this

How to reduce the transparent bitmap size (not dimensions)

In my android application I am working on canvas bitmaps (actually it is SCanvas from Samsung SPen SDK, but it does not matter), as a rule 90-95% of area of such bitmaps is transparent, so I expected to have not too large bitmap size in KB. But seems like bitmap size (in KB) does not depend on whether it is a simple background or complex picture, so for example if I have two images (sorry, I am a new user and I can't post any images):
1) empty frame (1000x700 px, background is transparent, color border)
2) full frame (1000x700 px, background is transparent, color border, a lot of text inside)
the size of both bitmaps are about 1.3MB.
But if I convert these bitmaps in byte arrays, the size of the first array is about 11 times less than the size of the second array.
I have to store a lot of such images as BLOBs in DB and display them as ImageView bitmaps.
Question 1: if I need to display 20 ImageView objects with such 95% transparent images, is there any way to not use 20 * 1.3MB at the same time? To me it seems like it should be only 1 alpha layer + 20 "data" layers.
Question 2: is there any way to reduce size (in KB) of an image with transparency without losing too much quality? The only way I saw is to decode the image byte array with inSampleSize = 2 and then create a scaled bitmap to keep the original image dimensions, something like:
originalBitmap.compress(Bitmap.CompressFormat.PNG, 0, stream);
byte[] bitmapBytes = stream.toByteArray();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length, options);
int bWidth = options.outWidth;
int bHeight = options.outHeight;
options.inSampleSize = 2;
options.inPreferredConfig = Bitmap.Config.ARGB_4444;
options.inJustDecodeBounds = false;
Bitmap scaledBitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length, options);
Bitmap finalBitmap = Bitmap.createScaledBitmap(scaledBitmap, bWidth, bHeight, true);
But the finalBitmap quality is unacceptable, no matter what options I used (inPreferredConfig, inDither).
Any other thoughts about the optimal way to handle the images with about 90% of simple transparent background and 10% of one-color "data"?
No matter what format you use, it will always end up as raw uncompressed (decoded) data before displaying, if it weren't decoded, you couldn't see it on the display. If you're worried about memory, try not to have all the images decoded all the time, just decode the one you have to show, and always release the others (don't keep a reference to them).

set image size to full screen in android

I'm having an android app in which I'm taking a picture using the android camera.
This picture is taken in the activity A and after that is sent to activity B where is edited.
This is how I receive my image in activity B:
Bundle extras = getIntent().getExtras();
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 5;
byte[] imageData = extras.getByteArray("imageData");
Bitmap myImage = BitmapFactory.decodeByteArray(imageData , 0, imageData.length,options);
Matrix mat=new Matrix();
mat.postRotate(90);
bitmapResult = Bitmap.createBitmap(myImage, 0, 0, myImage.getWidth(), myImage.getHeight(), mat, true);
ImageView imageView = (ImageView) findViewById(R.id.myPic);
imageView.setImageBitmap(bitmapResult);
As you can see I'm rotating the bitmap I receive with 90 using this:
Matrix mat=new Matrix();
mat.postRotate(90);
And here is my imageView in xml file:
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:id="#+id/myPic"
/>
The problem that I'm facing is that my picture is not full screen...it's almoust full screnn but not entirly.As you can see here:
If you could help me to increase a little bit its size I would really apreciate it.Thanks
EDIT:I wanna increase the width of my image only.Sorry!!
You can use ImageView.ScaleType
ImageView.ScaleType="CENTER_CROP"
You might have to crop the image. Because the image is not at its full height, the width of the image is proportionately scaled down, hence the black strips at the sides.
To be more specific, images taken using the phone's camera are probably intended to fit the screen exactly i.e. width-height ratio of image = width-height ratio of the screen. However, in your app the height of the image is constrained by the buttons at the top, so in order to maintain the width-height ratio of the image, the width of the image is scaled down proportionately.
Please refer to setScaleType
You could use CENTER_CROP to get full screen image and maintain the image's aspect ratio.

Memory efficient image resize in Android

I am trying to reduce the size of images retrieved form the camera (so ~5-8 mega pixels) down to one a a few smaller sizes (the largest being 1024x768). I Tried the following code but I consistently get an OutOfMemoryError.
Bitmap image = BitmapFactory.decodeStream(this.image, null, opt);
int imgWidth = image.getWidth();
int imgHeight = image.getHeight();
// Constrain to given size but keep aspect ratio
float scaleFactor = Math.min(((float) width) / imgWidth, ((float) height) / imgHeight);
Matrix scale = new Matrix();
scale.postScale(scaleFactor, scaleFactor);
final Bitmap scaledImage = Bitmap.createBitmap(image, 0, 0, imgWidth, imgHeight, scale, false);
image.recycle();
It looks like the OOM happens during the createBitmap. Is there a more memory efficient way to do this? Perhaps something that doesn't require me to load the entire original into memory?
When you decode the bitmap with the BitmapFactory, pass in a BitmapFactory.Options object and specify inSampleSize. This is the best way to save memory when decoding an image.
Here's a sample code Strange out of memory issue while loading an image to a Bitmap object
Are you taking the picture with the camera within your application? If so, you should set the picture size to a smaller one in the first place when they're being captured via android.hardware.Camera.Parameters.setPictureSize
Here is a similar question that I answered and show how to go about dynamically loading the proper image size.
out of memory exception + analyzing hprof file dump

Categories

Resources