public static void addBitmapToDisk(String filename, Bitmap paramBitmap,
Context paramContext) {
writeBitmapToDisk(filename, paramBitmap, paramContext,
Bitmap.CompressFormat.PNG);
}
public static void writeBitmapToDisk(String filename, Bitmap paramBitmap,
Context paramContext, Bitmap.CompressFormat paramCompressFormat) {
String str = constructFileName(filename);
if (paramBitmap != null) {
try {
FileOutputStream localFileOutputStream = paramContext
.openFileOutput(str, 0);
Log.e("CL", "localFileOutputStream" + localFileOutputStream);
paramBitmap.compress(paramCompressFormat, 100,
localFileOutputStream);
localFileOutputStream.flush();
localFileOutputStream.close();
return;
} catch (FileNotFoundException localFileNotFoundException) {
localFileNotFoundException.printStackTrace();
return;
} catch (IOException localIOException) {
localIOException.printStackTrace();
}
}
}
When I have 2 Mb file it compress up to 100 Kb using above code snippet and image quality is not hd or very clear. so is there any method for quality maintain in android while bitmap compression like instagram
Related
I know it's a very basic question but i am stuck to resolve this problem. I am working on image-sketching mobile app i have done all the work now I just want to store a resulting bitmap-image into internal memory.I have created a method "mageStore()" for image-storing purposes please write code there. I will be very thankful to you.
`private class ImageProcessingTask extends AsyncTask<Bitmap, Void, Bitmap> {
private ProgressDialog abhanDialog = null;
private Bitmap returnedBitmap = null;
#Override
protected void onPreExecute() {
returnedBitmap = null;
abhanDialog = new ProgressDialog(AbhanActivity.this);
abhanDialog.setMessage(getString(R.string.please_wait));
abhanDialog.setCancelable(false);
abhanDialog.show();
}
#Override
protected Bitmap doInBackground(Bitmap... params) {
final Bitmap sketched = AbhanSketch.createSketch(params[0]);
final Bitmap gaussianBitmap = AbhanEffects.applyGaussianBlur(sketched);
final Bitmap sepiaBitmap = AbhanEffects.sepiaTonnedBitmap(gaussianBitmap, 151, 0.71,
0.71, 0.76);
returnedBitmap = AbhanEffects.sharpenBitmap(sepiaBitmap, 0.81);
return returnedBitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
if (abhanDialog != null && abhanDialog.isShowing()) {
abhanDialog.cancel();
}
if (result != null) {
mImageView.setImageBitmap(result);
mImageView.buildDrawingCache();
bmap = mImageView.getDrawingCache();
storeImage(bmap);
isImage = false;
enableButton();
final boolean isFileDeleted = Utils.deleteFile(mPath);
if (DEBUG) {
android.util.Log.i(TAG, "File Deleted: " + isFileDeleted);
}
}
}
}
private void storeImage(Bitmap image) {
...please enter code here for image storing
}`
Here is your missing code inside a function
private void storeImage(Bitmap image) {
File sdcard = Environment.getExternalStorageDirectory() ;
File folder = new File(sdcard.getAbsoluteFile(), "YOUR_APP_DIRECTORY");
if(!folder.exists())
folder.mkdir();
File file = new File(folder.getAbsoluteFile(), "IMG_" + System.currentTimeMillis() + ".jpg") ;
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap = Bitmap.createScaledBitmap(bitmap, 400, (int) ( bitmap.getHeight() * (400.0 / bitmap.getWidth()) ) ,false);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
You can omit or edit this line
bitmap = Bitmap.createScaledBitmap(bitmap, 400, (int) ( bitmap.getHeight() * (400.0 / bitmap.getWidth()) ) ,false);
according to your need.
in your function write the following code
String path = Saveme(image,"image_name.jpg");
//path contains the full path to directory where all your images get stored internaly lolz but privately
for gallery
Saveme(image,"my image","my image test for gallery save");
and the defination for the Saveme() function is following
private String Saveme(Bitmap bitmapImage, String img_name){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Create imageDir
File mypath=new File(directory,img_name);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return directory.getAbsolutePath();
}
in gallery images are displayed from media store so you need to store image in media store the following code can help you for this
public void Saveme(Bitmap b, String title, String dsc)
{
MediaStore.Images.Media.insertImage(getContentResolver(), b, title ,dsc);
}
The code works fine, but the image that is produced looses a good amount of quality. Compression format used is PNG. And also how can I make the image to be saved as .png and not as a .file.
public static void writeBitmapToDisk(String filename, Bitmap paramBitmap,
Context paramContext, Bitmap.CompressFormat paramCompressFormat) {
Log.e("CL", "paramBitmap.getByteCount()" + paramBitmap.getByteCount());
String str = constructFileName(filename);
if (paramBitmap != null) {
try {
FileOutputStream localFileOutputStream = paramContext
.openFileOutput(str, 0);
Log.e("CL", "localFileOutputStream" + localFileOutputStream);
paramBitmap.compress(paramCompressFormat, 100,
localFileOutputStream);
localFileOutputStream.close();
return;
} catch (FileNotFoundException localFileNotFoundException) {
localFileNotFoundException.printStackTrace();
return;
} catch (IOException localIOException) {
localIOException.printStackTrace();
}
}
}
How to optimize this peace of code?
It takes about a minute on saveImage method.
class ObrolSimpleHost extends SimpleCameraHost {
private final String[] SCAN_TYPES = {"image/webp"};
private Context context = null;
public ObrolSimpleHost(Context _ctxt) {
super(_ctxt);
this.context = getActivity();
}
#Override public void saveImage(PictureTransaction xact, Bitmap bitmap) {
File photo = getPhotoPath();
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos = new FileOutputStream(photo.getPath());
bitmap.compress(Bitmap.CompressFormat.WEBP, 70, fos);
fos.flush();
fos.getFD().sync();
if (scanSavedImage()) {
MediaScannerConnection.scanFile(context, new String[]{photo.getPath()}, SCAN_TYPES, null);
}
} catch (java.io.IOException e) {
handleException(e);
}
}
#Override public void saveImage(PictureTransaction xact, byte[] image) {
// do nothing
}
}
I am calling ObrolSimpleHost from CameraFragment:
PictureTransaction xact = new PictureTransaction(getHost());
xact.needBitmap(true);
takePicture(xact);
Here is my own answer.
Fixed issues which CommonsWare mentioned and resize bitmap before compression by createScaledBitmap:
class ObrolSimpleHost extends SimpleCameraHost {
private final String[] SCAN_TYPES = {"image/" + imputType};
private Context context = null;
public ObrolSimpleHost(Context _ctxt) {
super(_ctxt);
this.context = getActivity();
}
#Override public void saveImage(PictureTransaction xact, Bitmap bitmap) {
File photo = getPhotoPath();
String path = photo.getPath().replace("jpg", imputType);
if (photo.exists()) {
photo.delete();
}
/**
* Resizing bitmap, so save some ms in compression
* http://stackoverflow.com/questions/17839388/creating-a-scaled-bitmap-with-createscaledbitmap-in-android
*/
final int maxSize = 960;
int outWidth;
int outHeight;
int inWidth = bitmap.getWidth();
int inHeight = bitmap.getHeight();
if(inWidth > inHeight){
outWidth = maxSize;
outHeight = (inHeight * maxSize) / inWidth;
} else {
outHeight = maxSize;
outWidth = (inWidth * maxSize) / inHeight;
}
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, outWidth, outHeight, false);
try {
FileOutputStream fos = new FileOutputStream(path);
if (imputType.equals("jpeg")) {
resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
} else {
resizedBitmap.compress(Bitmap.CompressFormat.WEBP, 70, fos);
}
fos.flush();
fos.getFD().sync();
if (scanSavedImage()) {
MediaScannerConnection.scanFile(context, new String[]{photo.getPath()}, SCAN_TYPES, null);
}
} catch (java.io.IOException e) {
handleException(e);
}
EventBus.getDefault().postSticky(new Events.PreparingBitmapEvent(path));
getActivity().finish();
}
#Override public void saveImage(PictureTransaction xact, byte[] image) {
// do nothing
}
}
Instead of standard bitmap use other library which build with JNI
In my case I am going to try Roid-WebP
I'm having an issue whereby when I write a bitmap to disk, it gets written to disk, however it gets written as a miniscule image (3kb or less in filesize).
I have checked that the source image is indeed the correct dimensions, however the output image seems shrunk despite configuring the bitmap options to not scale.
#Override
protected Void doInBackground(PPImage... params) {
String filename = "pp_" + position + ".jpg";
File externalStorageDirectory = Environment.getExternalStorageDirectory();
final File destination = new File(externalStorageDirectory, filename);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 16;
opts.inPurgeable = true;
opts.inScaled = false;
decode(opts, Uri.parse(params[0].getUri()), getActivity(), new OnBitmapDecodedListener() {
#Override
public void onDecoded(Bitmap bitmap) {
try {
FileOutputStream out = new FileOutputStream(destination, false);
writeImageToFileTask.this.holder.pathToImage = destination.getAbsolutePath();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), destination.getAbsolutePath(), destination.getName(), destination.getName());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
});
return null;
}
private void decode(BitmapFactory.Options options, Uri mUri, Context mContext, OnBitmapDecodedListener listener) {
try {
InputStream inputStream;
if (mUri.getScheme().startsWith("http") || mUri.getScheme().startsWith("https")) {
inputStream = new URL(mUri.toString()).openStream();
} else {
inputStream = mContext.getContentResolver().openInputStream(mUri);
}
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
listener.onDecoded(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
How do I ensure that the image being written to file is the same dimensions as the original source image?
You have specified sample size in your code, which will result in resizing:
opts.inSampleSize = 16;
Just remove this line, and the dimension of the output image should be the same.
About the usage of inSampleSize, according to official doc:
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.
My app uses the following piece of code to write out images I have resized into the app's data folder:
private void writeImage(Bitmap bmp, String filename)
{
try
{
FileOutputStream stream = openFileOutput(filename, MODE_WORLD_WRITEABLE);
bmp.compress(CompressFormat.PNG, 100, stream);
stream.flush();
stream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
I am able to read them in a file browser (ddms) and can confirm they appear to have been written.
However, any attempt to load the images results in non-null bitmaps with width and height of -1. I am using the following code to load them:
imageList = getFilesDir().list();
Bitmap bmp = null;
for(String img : imageList)
{
try {
bmp = BitmapFactory.decodeStream(openFileInput(img));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EDIT: On further inspection, it seems, after conversion the images are of density 160 (and not 240 as they should be) also, after testing a working application it seems the -1 mWidth and -1 mHeight on the bitmaps is irrelevent.
I had same problem.my data folder given smallest image.and cursor return null pointer exception on my getDestination method.then i fixed like it
public void captureNewPhoto() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
targetFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
targetUri = Uri.fromFile(targetFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, targetUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, 12);
}
And i use like in onActivityResult();
BitmapFactory.Options options = new BitmapFactory.Options();
networkBitmap = BitmapFactory.decodeFile(targetUri.getPath(),
options);
//ImageDialog(networkBitmap);
//String path = getRealPathFromUri(this, Uri.parse(targetUri.getPath()));
String myDeviceModel = android.os.Build.MODEL;
deviceName = Build.MANUFACTURER;
if (myDeviceModel.equals("GT-I9500")) {
} else if (deviceName.contains("samsung")) {
} else {
exif = ReadExif(targetUri.getPath());
if (exif.equals("6")) {
matrixx.postRotate(90);
} else if (exif.equals("7")) {
matrixx.postRotate(-90);
} else if (exif.equals("8")) {
matrixx.postRotate(-90);
} else if (exif.equals("5")) {
matrixx.postRotate(-90);
}
//matrixx.postRotate(-90);
}
networkBitmap = Bitmap.createBitmap(networkBitmap, 0, 0, networkBitmap.getWidth(), networkBitmap.getHeight(), matrixx, true);
Log.e("Taget File ", "Size " + targetFile.length());
if (networkBitmap != null) {
ImageSetting(networkBitmap, System.currentTimeMillis() + filename);
}
public void ImageSetting(Bitmap imageBitmap, final String fileName) {
networkBitmap = imageBitmap;
organizator(networkBitmap, fileName);
networkBitmap = null;
}` public void tamamlandiOndenFoto(Bitmap turnedBitmap, String filename) {
frontFotoFile = storeBitmap(networkBitmap, filename);
ondenFotoPath = ondenFoto.getAbsolutePath();
ondenFotoImageView.setImageBitmap(turnedBitmap);
}`
public File storeBitmap(Bitmap bp, String fileName) {
File sd = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File dest = new File(sd, fileName);
if (bp != null) {
try {
FileOutputStream out = new FileOutputStream(dest);
bp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
Log.e("Alinan hata ", " Catch hata ", e);
}
return dest;
} else {
return null;
}
}
I hope give you any idea for your problem.