Drawing small images on an existing PDF file by using PDF Libraries - android

I’m working on an app that creates a PDF file and I need to draw some small images on it.
The problem is that the drawn images on the PDF are blurry and have very low quality.
I've also tried to draw the images without scaling them and the same happens, they are blurry.
This is the snippet where I draw one image (I'm not using iText)
Bitmap calendarBitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.icon_200ppp_calendar);
pdfCanvas.drawBitmap(scaleToFitHeight(calendarBitmap, 16), xCoord, yCoord, null);
public Bitmap scaleToFitHeight(Bitmap b, int height) {
float factor = height / (float) b.getHeight();
return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factor), height, true);
}
I have the images in PNG and SVG (converted to VectorDrawable) and the result is the same.
This is the PNG:
This is the XML generated from the SVG file through Android Studio: SVG converted to VectorDrawable
These are the results:

You have to set the Density of the image bigger by an X factor.
For example:
Bitmap bm = new Bitmap(..);
bm.setDensity(bm.getDensity()*4);
// try with different X's: 2, 3, 4, 5, 6.
This loss in quality happens because when you write to PDF it will automatically resize your bitmap to fit that Canvas resolution. Also if you resize your image, bitmap you have to be careful if you have a 50X50 image and you want to resize to 50X10 it will mess up the image. Instead try to resize the Bitmap by a factor:
bm.getWidth()/4,
bm.getHeight()/4
and so on.

Related

Scale Bitmap lower than 4096x4096

I am currently working on an application that shows a Bitmap on an ImageView. Now the problem is, whenever trying to show a Bitmap larger than 4096x4096, it simply won't show up, stating that the image is too large to be shown.
For example: I want to load up an image that's 4128x2322 pixels
I to resize it to be smaller than 4096x4096.
I thought about something like this:
Bitmap bitmap;
if(b.getHeight() >= 4096) {
double f = b.getHeight() / 4096;
b = Bitmap.createScaledBitmap(b, (int)(b.getWidth() / f), (int)(b.getHeight() / f), false);
}else if(b.getWidth() >= 4096) {
double f = b.getWidth() / 4096;
b = Bitmap.createScaledBitmap(b, (int)(b.getWidth() / f), (int)(b.getHeight() / f), false);
}
imageview.setImageBitmap(b);
Somehow it won't work...
Any advices on how to scale properly?
Thanks in advance!
I got an intent which takes a picture and returns the image
That image will be stored somewhere else, which you will reference via a File or perhaps a content: Uri.
But to show the taken picture I need to scale it down first
Use BitmapFactory to load the bitmap. Use BitmapFactory.Options and its inSampleSize field to indicate how you want the image to be downsampled. This is covered in the documentation.
There is no device with resolution 4096X4096, your image going to be scaled any way. So instead trying to scale it up just top let the system to scale it down. How about taking the screen size in to calculation and provide the final scale by your self. Not only that you will save space but also improve performance.

Android canvas 50% larger than the imported image

When I create a Canvas from a bitmap that is generated with the BitmapFactory.decodeResources from a drawable resource that is a png image file of 400 x 400 pixels, the Canvas height and width are not 400 but 600!
In the code below, the drawable resource wind_scale is a png file that I generated with PHP as a 400 x 400 image.
Bitmap workingBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.wind_scale, options);
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas mCanvas = new Canvas(mutableBitmap);
int mHeight = mCanvas.getHeight(); int mWidth = mCanvas.getWidth(); both 600!!!!
Is this behavior expected? If so, why is there a 50% increase?
I am not 100% sure of the problem here but it's similar to another SO question (Getting weird font size after setting it programmatically). The problem there was also a 50% difference in values, and it was due to a comparison of sp units to pixels on the OP's device with a screen density ratio of 1.5.
You might check into BitmapFactory.Options; there are several scale and density flags that may help. My best guess is that the image is being scaled for the device and this is causing a measurement mismatch.
Canvas it's not related to the bitmap size but to the device available screen size. If you try that code on different devices (or virtual devices) you will find different results.
Canvas and Drawables

How to properly set a wallpaper on Android

It seems that setting a wallpaper on Android just doesn't work in any useful way.
If you get an image from your phone and set it as the wallpaper, it's way too big for the screen
If you resize it (either using a createBitmap() function that allows you to specify size, or the ridiculously useless createScaledBitmap()) it goes all jaggy and out of focus
If you use some freaky hacks to fix the quality of the image, it's better, but still not perfectly clear by any stretch.
If you attempt to get the current wallpaper and set that, it still seems to make it too big. It appears to give you the original image file, forcing you to resize it, which doesn't work.
Now, the phone's internal software is perfectly capable of resizing an image to be smaller with no reduction of quality. Why does it not share this functionality?
WallpaperManager wallpaperManager = WallpaperManager.getInstance(Spinnerz.this);
// gets the image from file, inexplicably upside down.
Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "DCIM/Camera/Zedz.jpg");
// use some rotation to get it on an angle that matches the screen.
Matrix bitmapTransforms = new Matrix();
bitmapTransforms.setRotate(90); // flip back upright
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),bitmapTransforms, false); // create bitmap from bitmap from file, using the rotate matrix
// lets set it exactly to the resolution of my Samsung Galaxy S2: 480x800 pixels.
// This function appears to exist specifically to scale a bitmap object - should do a good job of it!
bitmap = Bitmap.createScaledBitmap(bitmap, 480, 800, false);
wallpaperManager.setBitmap(bitmap);
// result is quite a jaggy image - not suitable as a wallpaper.
PIC:
Try this ,
Display d = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = d.getWidth();
int height = d.getHeight();

Scaling image in Android

I tried to scale an high-resolution image to the desired size of my android and then set it as wallpaper, but as result I have a scaled image with 'annoying alternate rows' that make the picture NOT attractive.
int newWidth = wallpaperManager.getDesiredMinimumWidth();
int newHeight = wallpaperManager.getDesiredMinimumHeight();
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmapOrg, newWidth, newHeight, true);
You are scaling the bitmap correctly.
You could try downloading GIMP (free software) and scale your image to match the main 3 resolutions of android phones. This may produce a better result.

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