I wanna to develop a compressed size for images by factors.
after I googled it, I found I can use compress function in bitmap as following
myImage.compress(Bitmap.CompressFormat.JPEG, compressRatio, out);
possible values for compressRatio is 100, 50 and 25
so that in case of 100 the saved image in original size says (1MB) in case of 50 save size 0.5MB and 25 save in 0.25MB image size.
but actual after I pass the values I get different values for example
for 100 the size is about 1.4M, for 50 sizes is about 250k, for 25
sizes is about 150k, the right scaling should be if for 100 the size
is about 1.4M, for 50 sizes is about 700k, for 25 sizes is about 300K
can anyone help me to understand why it not work as expected?
==========================================================
Edit 1:
as CommonsWare mentioned this can't be achieved by compress() so is there any suggestion to make what I need real
Hint: I don't want change its width and height I need to keep them as original image dimensions but in different sizes.
scale down image size with specified ratio - android
This has nothing to do with the compress() method on Bitmap. Given an existing Bitmap, you can call createScaledBitmap() to create a scaled bitmap.
so that in case of 100 the saved image in original size says (1MB) in case of 50 save size 0.5MB and 25 save in 0.25MB image size.
That is not how the compression factor parameter to compress() works. The exact meaning of that value depends on the image format. For JPEG, it controls how lossy the compression can be, but it is not a linear scale. For example, a value of 0 does not allow you to save an image as a zero-byte file.
Related
I am saving three imageviews to one bitmap after the user edits the image(s). The problem is that once the final result is saved, the resulting saved image doesn't always look the same on different screen resolutions.
On my phone, which is a Asus Padfone X, the saved image comes out perfectly. On my partners phone, Note 6, the positioning of the saved images on the resulting bitmap are off. (See example below)
I am using the following code to save the imageviews to a single image:
Bitmap mainBmp = backImage.getDrawingCache();
Bitmap centerBmp = centerImage.getDrawingCache();
Bitmap handleBmp = handleImage.getDrawingCache();
Canvas canvas = new Canvas(mainBmp);
canvas.drawBitmap(centerBmp, 17, 95, null);
canvas.drawBitmap(handleBmp, 17, 85, null);
Which saves properly on my phone but not one with a bigger screen/higher resolution. How do I ensure the resulting saved image looks the same regardless of the device it is saved on?
EXAMPLE OF DIFFERENCE
You need to scale. For example, lets say that device 1 is 500x1000 pixels and device 2 is 600x1200. Lets say the bitmap is 300x400 and starts at an offset of 30 pixels in x and 100 in y.
The bitmap needs to grow in size by the ratio of the two screens sizes. So it would need to be 300*(600/500) pixels wide and 400*(1200/1000) pixels big. The offset would need to scale as well- to 30*(600/500) and 100*(1200/1000).
Please note that when scaling you may get stretching, pixelation, and other image defects. The more you stretch the worse it will be. Shrinking can also give defects, but these tend to be more minor.
This is the simple case- the two screens I gave have the same aspect ratio (ratio of width:height). In the case of different aspect ratios, you need to choose:
1)Keep the aspect ratio of the image the same. This will mean you'll have blank space in 1 direction, but the image won't be effected.
2)Allow the aspect ratio of the image to change. This will leave no blank space, but will skew the image.
For #2, use the same code as above. For #1, figure out which dimension needs to scale the least, and use that to scale x and y.
It is not possible to scale from any size phone to any size phone without any defects on a generic image. You'll have to choose between the two options above.
I also found that if I instead use imageview.getWidth() and imageview.getHeight(), I can position each "layer" where I need it to be no matter the screen size. I tested this method on a small android device all the way up to a tablet and the saved image came out perfect across all devices.
What I did was determine the pixel size of each image("layer") using Photoshop. I then used an online px to dp calculator/converter to determine the correct dp size of each layer. I set specific dp width and height for each layer in the layout. For each layer I needed to save to the main image, I calculated the x and y dimensions by taking the mainimageviews height and width and subtracting the pixels needed from the edge to the respective edge of that layer. Through trial and error, I ran the app a few times to get the exact positioning of each layer I wanted. The result of the saved image was exactly the way it looked to the user. Hope this helps someone else in the future.
Well, i am trying to reduce the size(bits) of an image, which will be taken using camera. I have already reduced it by reducing its height and width. But a lot of questions came infront.
IIsnt it possible that within same height & width- an image can contain more/less resolutions. I mean- cant resolution vary within images which have same height & width?
Is there other properties of image/color, which we can change and make the total image size(bits) become less?
Any other solutions? :-)
Use Bitmap to compress your image.
This can be done by calling;
Bitmap bm=//intialize your image here
FileOutputStream fos=//intialize your OutputStream here
bm.compress(Bitmap.JPEG, 50, fos)// the Number stands for the quality of the image, the format of the image can be changed if you want to
For further information see the Android API here.
I am trying to place an image as background in my TextView. I want the image to get changed by pressing a button. At the first image gets loaded but when I try for next time it says OutOfMemoryError.
My Code:
int [] Quo = {R.drawable.wallpaper10,R.drawable.wallpaper2,R.drawable.wallpaper3,R.drawable.wallpaper4};
txtView.setBackgroundResource(Quo[j] );
It works perfectly if i give
txtView.setBackgroundResource(Quo[0]);
I am new to android development please help me resolve issue.
image memory usage is based on multiple things:
resolution of the image.
where the image file is located (the density qualifier of the drawable folder) compared to on which screen density the app is running on.
which bitmap format you used .
whether or not the image is 9-patch image.
so , for example, if you have a 100x100 image, and the file is in "drawable-mdpi" yet it runs on an xhdpi device , and the bitmap format is the default one, and it's not a 9-patch image, the bitmap would take:
100*100 * 4 *4 = 160,000 bytes.
the 100*100 is because of the number of pixels for width and height.
the first 4 is because on the default bitmap format, each pixel takes 4 bytes.
the second 4 is because the density is 2 times larger in both width and height (2*2=4).
so, if this is the only code you show, i think you use too much memory because of your images.
one thing that you could do is to downsample them.
I am working on an app for image processing.
I use BitmapFactory.decodeStream to load an image, when I press the button to pass the image to setPixel, it leads to OutOfMemoryError.
I tried smaller image is okay.
Anyway to load a big image and immediately save it in Bitmap with a smaller size?
Use BitmapFactory.Options.inSampleSize to decode a smaller bitmap.
public int inSampleSize
Since: API Level 1
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 will try to fulfill this request, but the resulting bitmap may
have different dimensions that precisely what has been requested.
Also, powers of 2 are often faster/easier for the decoder to honor.
Actually i am developing one application, where my requirement is like i have to scale large size images to some predefined size as per user selection. eg,Suppose i have an image which is of 1Mb and user select it to convert it into an image of size 100kb then i have to resize that image to 100kb.
last one day i am trying to achevive this with Bitmap APIs but i am not able to achieve the exact size what user want. Sometimes its very large sometimes very small. So please if anyone knows how to resize image in android to exact size(which is changing as per user selection).
Please help me out in this.
If only the file size matters, you will want to use an image file format that does not use compression. You should be able to take an image with attributes such as width, height, bit-depth, and so on and calculate the expected file size for such an image.
So, using such a file format you start with your original image and you have
File size = width x height x bit depth + metadata/overhead.
I assume you want to maintain the original aspect ratio also. In that case, you can probably just figure out the % reduction in file size from the current file size, and multiply the width and height by the same %. Scale your image using a bitmap image manipulation API and then save it. It should be close to the file size you are looking for.
Specific to the Android Bitmap api you can use getByteCount() to determine how many bytes the image currently takes up. You can also use getConfig() to determine how many bytes per pixel.
So, your final goal file size converted to bytes divided by the number of bytes per pixel, gives you the number of pixels you are allowed. Number of pixels allowed divided by the number of pixels in your current image will give you the scaling factor. Use the scaling factor and scale the image keeping the current aspect ratio and you should have a bitmap with a number of pixels close to your goal. Then save in a file format that does not use compression.