I'm making bitmap (that will be printed on paper, later) and using canvas to draw on it.
But after saving it always have 72 dpi resolution. I tried to use bitmap.setDensity(96);but it does not seems to work.
This is how I make bitmap and save it, nothing fancy
Bitmap outBitmap = Bitmap.createBitmap(378,559,Bitmap.Config.RGB_565);
OutputStream outStream = null;
File file = new File(Environment.getExternalStorageDirectory(),
"96dpiBitmap.png");
try {
outStream = new FileOutputStream(file);
outBitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
// doh
} catch (IOException e) {
// doh
}
So. How do I save bitmap with dpi > 72?
you have to create scaled bitmap from the original one for ex :
MyNewBitmap = Bitmap.createScaledBitmap(myOldOne,612,612,false);
where 612 width and 612 height the result will be image squared. i'm using this method to prevent instagram from scaling or cutting my image so its perfectly fit into instagram image cropping :).
anyway you have to find the proper way to scale your image to fit 72dpi. i guess 800x600 will do the trick. try to create new bitmap and scale the old one and then save the newBitmap.
good luck
Related
I'm loading an image in to a number of different ImageViews, each with different ScaleTypes. Additionally, some images can be rotated using a Glide transformation before being displayed.
I'd like to be able to make a copy of the original image and crop, rotate, resize it in the same way as it is displayed in the ImageViews.
At the moment I'm grabbing a Bitmap from the ImageView itself but the quality is obviously much lower than the original source image.
Is there a way that I could use the properties of this bitmap and apply them to the original image?
For saving file you can do this
FileOutputStream out = null;
try {
out = new FileOutputStream(filename);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
the original answer is here
For your rotating, cropping, resizing image, you can use canvas and matrix Android APIs.
Here is an answer
And here is Canvas API
If you are doing that too often in your app, then maybe you are using the wrong library. Please refer this post for more info. https://medium.com/#multidots/glide-vs-picasso-930eed42b81d
I am working with Canvas in Android Studio, have .png image on canvas and want to save it to sd card. Is it possible?
if yes then how?
thanks and regards.
This code may help you (Saving canvas to bitmap on Android)
Bitmap toDisk = null;
try {
// TODO: Get the size of the canvas, replace the 640, 480
toDisk = Bitmap.createBitmap(640,480,Bitmap.Config.ARGB_8888);
canvas.setBitmap(toDisk);
toDisk.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File("arun.jpg")));
} catch (Exception ex) {
}
You should have created Canvas with new Canvas(myBitmap);. So when you draw on the Canvas, it draws to your bitmap.
String fileName = Environment.getExternalStorageDirectory() + "/test.png";
OutputStream stream = new FileOutputStream(fileName);
/* Write bitmap to file using JPEG or PNG and 80% quality hint for JPEG. */
myBitmap.compress(CompressFormat.PNG, 80, stream);
stream.close();
Usually I find everything I need using the search function of StackO. But now (success less) I’m really trying hard to resize a JPEG from SD Card without getting bad quality. As follows, you can see that the original Image is clean and perfectly readable. After resizing I will always get a blurred result.
Original: https://www.dropbox.com/s/l5h4cdkz29vkapw/signature.jpg?dl=0
Scaled: https://www.dropbox.com/s/tobijbu5hisf9rz/signature_small.jpg?dl=0
At the following code passage you can see everything I tried without success (I hope I am wrong, but I think this passage includes all the really useable answers from StackO.) :
public void saveSignature(View view) throws IOException {
image = signature.getImage();
File sd = Environment.getExternalStorageDirectory();
File final_location = new File(sd, "signature.jpg");
try {
if (sd.canWrite()) {
final_location.createNewFile();
OutputStream os = new FileOutputStream(final_location);
image.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close();
//Bitmap resized = Bitmap.createScaledBitmap(image,(int)(image.getWidth()*0.4),(int)(image.getHeight()*0.4), false);
//Bitmap resized = Bitmap.createScaledBitmap(image, 300,75, false);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
// "works but Color ist gray from sampling" bmOptions.inSampleSize = 5;
final_location = new File(sd, "signature_small.jpg");
final_location.createNewFile();
os = new FileOutputStream(final_location);
Bitmap b= BitmapFactory.decodeFile(sd +"/signature.jpg",bmOptions);
Bitmap out = Bitmap.createScaledBitmap(b, 349, 86, true); //also tyed false (without any Change)
out.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
It would be nice to get some answers or links to samples for Android (4.0 and higher).
Thanks for your help in advance,
Tough!!
How do you expect to scale down an image without losing quality?
Anyway, to scale down correctly you need to blur the image first, preferably with a Gaussian kernel, but a box blur will probably be fine. The kernel size should match the scale you wish to scale to. After that you can scale down the image with any interpolation technique. Lanzcos, bilinear or even nearest neighbor will be good enough. An alternative approach is to use some kind of area sampling, where each pixel in the target image is a mean of an area of pixels in the source image. Another alternative is to use some kind of supersampling.
If you don't do any of these, you'll end up with crappy images. But even if you do it correctly, you will lose quality. Because the scaled down image will have less information than the original.
I am saving small image about width = 30px and height = 30px and file type is png on sdcard. After saving the image when I view it on my sdcard, the image appears bigger with low resolution. The original image however is crystal clear. Below is my code, please tell me how can I make the image quality better and also let the image be it's original size and not appear bigger. Thanks
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.b_01);
ByteArrayOutputStream bStream1 = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, bStream1);
File f1 = new File(Environment.getExternalStorageDirectory() + File.separator + "AppName" + "/bmp.png");
if(!f1.exists()) {
try {
f1.createNewFile();
FileOutputStream fs1 = new FileOutputStream(f1);
fs1.write(bStream1.toByteArray());
fs1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I've got an ImageView, in its onDraw(canvas),
i tried:
canvas.drawBitmap(...);//draw an extremely large background 3264 * 2448 pixels
canvas.drawLine(...);//draw target
My question is, how can I save this canvas into a sth like png? Thanks!
From the question here:
Drawing on Canvas and save image
imgView.setDrawingCacheEnabled(true);
Bitmap b = imgView.getDrawingCache();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(getFileName());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
b.compress(CompressFormat.PNG, 95, fos);
You can save the view cache image to the disk as png.