save image file with bitmap factory - java

I'm encountering an issue with bitmap factory.
I've got a method to reduce and rotate an image to show a preview in an image view, but I would like to save this with the new size.
I'm just turning around with inputfilestream and outputfilestream but don't get to save it.
Is anybody know a clear method to put my bitmap in an outpufilestream?
Thanks a lot
here's my code
#Override
protected void onResume() {
super.onResume();
File[] fileArray;
final File root;
File chemin = Environment.getExternalStorageDirectory();
String filepath = chemin + "/SmartCollecte/PARC/OUT/" + fichano + "_" + conteneur_s+"_"+cpt+".jpg";
try {
decodeFile(filepath);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}}
public void decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap b1 = BitmapFactory.decodeFile(filePath, o2);
Bitmap b = ExifUtils.rotateBitmap(filePath, b1);
FileOutputStream fos = new FileOutputStream(filePath);
b.compress(Bitmap.CompressFormat.PNG,100,fos);
fos.close();
showImg.setImageBitmap(b);
}

Have you tried doing it like this?
Assuming bitmap is bitmap you want to save.
Also, take a look at some existing system directories.
final FileOutputStream fos = new FileOutputStream(new File(filepath + "_scaled.jpg"));
try {
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
} catch (IOException e) {
// handle exception
} finally {
fos.close
}
Source
Where first parameter of Bitmap.compress() is your desired output format (see CompressFormat) and the second parameter is compression quality.

ok I found out what was missing.
had to create a new byte array to convert my bitmap to file :
String filepathcomp = Environment.getExternalStorageDirectory()+"/SmartCollecte/PARC/OUT/"+ fichano + "_" + conteneur_s+"_"+cpt+".jpg";
File f = new File(filepathcomp);
Bitmap newbitmap = b;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
newbitmap.compress(Bitmap.CompressFormat.JPEG,80,bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos = new FileOutputStream(f);
fos.write(bitmapdata);
fos.flush();
fos.close();

Related

How to reduce image size mb to kb in android?

I am trying to reduce image size mb to kb using bitmap. but the code I have done is not working. I am new in android programming please can anyone help.
thanks.
I expect like this to convert image.
enter image description here
I have tried this
public void compressBitmap(File file, int sampleSize, int quality) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = sampleSize;
FileInputStream inputStream = new FileInputStream(file);
Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, options);
inputStream.close();
File files = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath());
FileOutputStream outputStream = new FileOutputStream(files);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.close();
long lengthInKb = file.length() / 1024; //in kb
if (lengthInKb > 1000) {
compressBitmap(file, (sampleSize*2), (quality/4));
}
selectedBitmap.recycle();
} catch (Exception e) {
e.printStackTrace();
}
}

Base64 Encoding takes too long time in Android

I'm capturing an Image with the Camera. I save the File in the public photo directory and save the Uri to that file.
I want to save the Image in a Base64 String and put it on a HashMap to put it then in a XML file later.
protected Void doInBackground(Void...voids) {
options.inJustDecodeBounds = false;
//Bitmap bmp = BitmapFactory.decodeFile(imageFilePath,options);
InputStream in = null;
try {
in = getContentResolver().openInputStream(Uri.parse(mCurrentPhotoPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
options.inSampleSize = 2;
Bitmap image = BitmapFactory.decodeStream(in,null,options);
int imgHeight = image.getHeight();
int imgWidth = image.getWidth();
while(imgHeight>2000){
imgHeight = imgHeight / 2;
}
while(imgWidth>2000){
imgWidth = imgWidth / 2;
}
Bitmap test = Bitmap.createScaledBitmap(image,imgWidth,imgHeight,false);
String stest = base64EncodeDecode.encodeToBase64(test);
items.put("image",base64EncodeDecode.encodeToBase64(test);
return null;
}
The Base64 takes too long to encode it.
encodeToBase64 Method
public String encodeToBase64(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
return Base64.encodeToString(b, Base64.DEFAULT);
}
Can you tell me if I do something wrong while encoding?
I hope my problem is clear.
Kind Regards!
If you are getting !!! FAILED BINDER TRANSACTION !!! error is probably because you are passing to much data to the other Activity, there is a limit of how much you can send. Try compressing your image to 50% or 30% image.compress(Bitmap.CompressFormat.JPEG, 50, baos);

Why i cannot show my byte[] image after converting it from bitmap?

I'm trying to write a method that accepts an image(Bitmap) and returns a byte[] array. finally, I try to write this byte[] array to a folder so I can see the difference, but my byte[] arraycan not displayed, and in addition, it is not scaled down! This is my method:
private byte[] changeSize(Bitmap image) {
byte[] picture;
int width = image.getWidth();
int height = image.getHeight();
int newHeight = 0, newWidth = 0;
if (width > 250 || height > 250) {
if (width > height) { //landscape-mode
newHeight = 200;
newWidth = (newHeight * width) / height;
} else { //portrait-mode
newWidth = 200;
newHeight = (newWidth * height) / width;
}
} else {
Toast.makeText(this, "Something wrong!", Toast.LENGTH_LONG).show();
}
Bitmap sizeChanged = Bitmap.createScaledBitmap(image, newWidth, newHeight, true);
//Convert bitmap to a byte array
int bytes = sizeChanged.getByteCount();
ByteBuffer bb = ByteBuffer.allocate(bytes);
sizeChanged.copyPixelsFromBuffer(bb);
picture = bb.array();
//Write to a hd
picturePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String fileName = edFile.getText().toString() + "_downscaled" + ".jpg";
File file = new File(picturePath, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(picture);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return image;
}
I tried several hours to get my byte[] array visible, but I could simply not do this. Any help or hints to show me where I derail is/are very appreciated.
This was working for me
public static Bitmap byteArraytoBitmap(byte[] bytes) {
return (BitmapFactory.decodeByteArray(bytes, 0, bytes.length));
}
public static byte[] bitmaptoByteArray(Bitmap bmp) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); //PNG format is lossless and will ignore the quality setting!
byte[] byteArray = stream.toByteArray();
return byteArray;
}
public static Bitmap bitmapFromFile(File file) {
//returns null if could not decode
return BitmapFactory.decodeFile(file.getPath());
}
public static boolean saveImage(Bitmap image, String filePath) {
LogInfo(TAG, "Saving image to: " + filePath);
File file = new File(filePath);
File fileDirectory = new File(file.getParent());
LogInfo(TAG, fileDirectory.getPath());
if (!fileDirectory.exists()) {
if (!fileDirectory.mkdirs()) {
Log.e(TAG, "ERROR CREATING DIRECTORIES");
return false;
}
}
try {
file.createNewFile();
FileOutputStream fo = new FileOutputStream(file);
fo.write(bitmaptoByteArray(image));
fo.flush();
fo.close();
return true;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}

Camera to nfc - best photoquality

For my application, I need to save a photo, taken from camera of a device, on an 7.7k nfc chip.
In the onActivityResult, I resize the bitmap as here :
String fileName = "original";
String path = Environment.getExternalStorageDirectory() + "/" + fileName + ".jpg";
//Resizing
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap current = BitmapFactory.decodeFile(path);
Bitmap resized = resizeBitMapImage(path,largeur,(int)(largeur*1.8));
with
public static Bitmap resizeBitMapImage(String filePath, int targetWidth, int targetHeight) {
Bitmap bitMapImage = null;
try {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
double sampleSize = 0;
Boolean scaleByHeight = Math.abs(options.outHeight - targetHeight) >= Math.abs(options.outWidth
- targetWidth);
if (options.outHeight * options.outWidth * 2 >= 1638) {
sampleSize = scaleByHeight ? options.outHeight / targetHeight : options.outWidth / targetWidth;
sampleSize = (int) Math.pow(2d, Math.floor(Math.log(sampleSize) / Math.log(2d)));
}
options.inJustDecodeBounds = false;
options.inTempStorage = new byte[128];
while (true) {
try {
options.inSampleSize = (int) sampleSize;
Log.v(LOG_TAG,"inSampleSize" + options.inSampleSize);
bitMapImage = BitmapFactory.decodeFile(filePath, options);
break;
} catch (Exception ex) {
try {
sampleSize = sampleSize + 1 ;
} catch (Exception ex1) {
}
}
}
} catch (Exception ex) {
}
return bitMapImage;
}
(Found on SO)
And then, I save it on the chip with :
NdefRecord picRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "image/jpeg".getBytes(), null, byteArray);
When I choose a width of 200, and a compression of 50, the picture takes about 7k, but the quality is quite low. The bitmap is a contact photo.
So my questions :
What should I use as width, height, compression, in order to get the best photo quality (less than 7k?
Should the camera be set on high or low resolution ?
PNG or JPEG compression ?

DecodeStream throwing null while storing in bitmap

This is my code... I am getting exception NULL at imageBitmap = BitmapFactory.decodeStream(is2,null, options);
First time it can decode but why now, decodeStream throwing null ?
public void showImageThumb(FileInputStream is)
{
final int IMAGE_MAX_SIZE = 100;
FileInputStream is2 = is;
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap imageBitmap = BitmapFactory.decodeStream(is,null, options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int height = options.outHeight;
int width = options.outWidth;
int scale = 1;
if ( height > IMAGE_MAX_SIZE || width > IMAGE_MAX_SIZE)
{
scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(options.outHeight, options.outWidth)) / Math.log(0.5)));
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
options = new BitmapFactory.Options();
options.inSampleSize = scale*2;
imageBitmap = BitmapFactory.decodeStream(is2,null, options);
height = options.outHeight;
width = options.outWidth;
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); //ERROR HERE
imageSelectedThumb = baos.toByteArray();
you get a nullpointer exception because you are copying the
is
reference in
is2
so when you close is, you are closing is2 too. Instead of assing is to is2 you have to create a new InpustStream
You have to make a deep copy of InputStream Object.Source Code in details ,please see https://stackoverflow.com/a/12797510/952386

Categories