I have a function convert image to array byte (to save image into database sqlite). I have a problem, how to compress image and avoid out of memory error?
This is my code
Thanks in advance.
public byte[] ConverttoArrayByte(ImageView img)
{
try{
BitmapDrawable bitmapDrawable = (BitmapDrawable) img.getDrawable();
Bitmap bitmap = bitmapDrawable.getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
return stream.toByteArray();
}catch (NullPointerException e){
Log.d("Tag", "Null");
e.printStackTrace();
}
return null;
}
You can try to use a small function that resizes the image:
public static Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
float bitmapRatio = (float)width / (float) height;
if (bitmapRatio > 1) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}
And call this function in this way Bitmap bitmap = GetAttachmentsUtils.getResizedBitmap(bitmap, maxSize); to get the resized bitmap.
Then you can compress it using bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); and perform the same operations you were doing previously.
Related
i am trying to save some images to a web server. So what I doe is I convert my file in android to Base64 string, send it to my server and save the Base64 string in my database. When I need, I read the string from that database and decode it. But there is some problem with my image because the image is all grey.
This is my code to convert the image to base64:
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(), options);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int imageWidth = options.outWidth;
if (imageWidth > widthPixels) {
myBitmap.compress(Bitmap.CompressFormat.JPEG, 50, byteArrayOutputStream);
} else {
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
}
byte[] byteArray = byteArrayOutputStream.toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
Then I send the string "encoded" to the server and save it in the database.
And this is part of my image saved in the server
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkz
ODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2Nj
for some reason there are some "\n" and I think that this is causing my problem. I have already tried to remove them with a replaceAll but didn't worked.
This is the output I get
This is my database structure:
I'm saving the encoded 64base image as a string in the column caled "imagemBase". Could the problem be in the type or in the codification that i'm using?
I using this methods an worked for me:
public static String encodeBitmap(Bitmap bitmap) {
if (bitmap != null) {
bitmap = resize(bitmap, 800, 800);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] byteArrayImage = baos.toByteArray();
return Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
}
return null;
}
public static Bitmap decodeBitmap(String encodedImage) {
byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
}
public static Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
if (maxHeight > 0 && maxWidth > 0) {
int width = image.getWidth();
int height = image.getHeight();
float ratioBitmap = (float) width / (float) height;
float ratioMax = (float) maxWidth / (float) maxHeight;
int finalWidth = maxWidth;
int finalHeight = maxHeight;
if (ratioMax > ratioBitmap) {
finalWidth = (int) ((float) maxHeight * ratioBitmap);
} else {
finalHeight = (int) ((float) maxWidth / ratioBitmap);
}
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
return image;
} else {
return image;
}
}
I have solved the problem. When I converted the image to base64 the string that I received hade some + cahrs in it and for some reason when I sent it to the server the + was replaced with a blank space. I needed to make a replace on the php file where I replaced all black spaces with the + character before saving the string in the database.
I need to build an app which take a picture or select an image from the gallery and I need to send it to the server with a size of 50kb.
Until now, I only find a code in which you can resize the width and height of the bitmap, but thanks to it, the bitmap loses quality.
public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
float bitmapRatio = (float)width / (float) height;
if (bitmapRatio > 1) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}
Thanks in advance!
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 100;
while ( baos.toByteArray().length > 1024*50) {
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
options -= 10;
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
return bitmap;
Hey everyone this is code through which we can resize an image but there is an in 1st and 2nd line and i cannot solve this please help me
Bitmap image2 = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(image2);
/*String incident_ID = IncidentFormActivity.incident_id;*/
String imagepath = "\1.jpg";
File file = new File(imagepath);
double xFactor = 0;
double width = Double.valueOf(image2.getWidth());
Log.v("WIDTH", String.valueOf(width));
double height = Double.valueOf(image2.getHeight());
Log.v("height", String.valueOf(height));
Log.v("Nheight", String.valueOf(width*xFactor));
Log.v("Nweight", String.valueOf(height*xFactor));
int Nheight = 480;
int NWidth = (int) ((Nheight * width)/height);
Bitmap bm = Bitmap.createScaledBitmap( image2,NWidth, Nheight, true);
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bm.compress(CompressFormat.PNG, 100, ostream);
ostream.close();
use this Function . it works Perfect for me
static public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
float bitmapRatio = width / height;
if (bitmapRatio > 0) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}
here Max size refer to the pixels till the Image will be redudes
for example if you want to reduce to 640px
simply Call `
Bitmap image2 = (Bitmap) data.getExtras().get("data");
getResizedBitmap(image2 , 640);
I am developing a application in which I want to resize captured image before store it in specified folder of sdcard.
I have used all the permissions required for write the data in sdcard but still I am unable to do it.
my code:
try{
Bitmap bitmap = Constant.decodeFile(fileName);
bitmap = Bitmap.createScaledBitmap(bitmap, 480, 320, true);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bytes);
File f = new File(fileName.toString());
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
}catch (Exception e) {
e.printStackTrace();
}catch (OutOfMemoryError o) {
o.printStackTrace();
}
You have forgot to flush the Stream after writing data into into. use FileOutputStream.flush() after writing data... and
try this...
File file = new File(fileName.toString());
try {
FileOutputStream stream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 100, stream);
stream.flush();
stream.close();
} catch (Exception e) {
// TODO: handle exception
}
You can use createBitmap() to resize the original image.
FOllowing are the parameters:
(Bitmap source, int x, int y, int width, int height)
source The bitmap we are subsetting
x The x coordinate of the first pixel in source
y The y coordinate of the first pixel in source
width The number of pixels in each row
height The number of rows
Example:
Bitmap newbitmap = Bitmap.createBitmap(originalBitmap, 2, 2, bitmap.getWidth() - 4, bitmap.getHeight() - 120);
There is a nice tutorial on resizing images:
BitmapScaler scaler = new BitmapScaler(getResources(), R.drawable.moorwen, newWidth);
imageView.setImageBitmap(scaler.getScaled());
BitmapScaler class follows:
class BitmapScaler {
private static class Size {
int sample;
float scale;
}
private Bitmap scaled;
BitmapScaler(Resources resources, int resId, int newWidth)
throws IOException {
Size size = getRoughSize(resources, resId, newWidth);
roughScaleImage(resources, resId, size);
scaleImage(newWidth);
}
BitmapScaler(File file, int newWidth) throws IOException {
InputStream is = null;
try {
is = new FileInputStream(file);
Size size = getRoughSize(is, newWidth);
try {
is = new FileInputStream(file);
roughScaleImage(is, size);
scaleImage(newWidth);
} finally {
is.close();
}
} finally {
is.close();
}
}
BitmapScaler(AssetManager manager, String assetName, int newWidth)
throws IOException {
InputStream is = null;
try {
is = manager.open(assetName);
Size size = getRoughSize(is, newWidth);
try {
is = manager.open(assetName);
roughScaleImage(is, size);
scaleImage(newWidth);
} finally {
is.close();
}
} finally {
is.close();
}
}
Bitmap getScaled() {
return scaled;
}
private void scaleImage(int newWidth) {
int width = scaled.getWidth();
int height = scaled.getHeight();
float scaleWidth = ((float) newWidth) / width;
float ratio = ((float) scaled.getWidth()) / newWidth;
int newHeight = (int) (height / ratio);
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
scaled = Bitmap.createBitmap(scaled, 0, 0, width, height, matrix, true);
}
private void roughScaleImage(InputStream is, Size size) {
Matrix matrix = new Matrix();
matrix.postScale(size.scale, size.scale);
BitmapFactory.Options scaledOpts = new BitmapFactory.Options();
scaledOpts.inSampleSize = size.sample;
scaled = BitmapFactory.decodeStream(is, null, scaledOpts);
}
private void roughScaleImage(Resources resources, int resId, Size size) {
Matrix matrix = new Matrix();
matrix.postScale(size.scale, size.scale);
BitmapFactory.Options scaledOpts = new BitmapFactory.Options();
scaledOpts.inSampleSize = size.sample;
scaled = BitmapFactory.decodeResource(resources, resId, scaledOpts);
}
private Size getRoughSize(InputStream is, int newWidth) {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, o);
Size size = getRoughSize(o.outWidth, o.outHeight, newWidth);
return size;
}
private Size getRoughSize(Resources resources, int resId, int newWidth) {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeResource(resources, resId, o);
Size size = getRoughSize(o.outWidth, o.outHeight, newWidth);
return size;
}
private Size getRoughSize(int outWidth, int outHeight, int newWidth) {
Size size = new Size();
size.scale = outWidth / newWidth;
size.sample = 1;
int width = outWidth;
int height = outHeight;
int newHeight = (int) (outHeight / size.scale);
while (true) {
if (width / 2 < newWidth || height / 2 < newHeight) {
break;
}
width /= 2;
height /= 2;
size.sample *= 2;
}
return size;
}
}
http://zerocredibility.wordpress.com/2011/01/27/android-bitmap-scaling/
if you are using PNG format then it will not compress your image because PNG is a lossless format. use JPEG for compressing your your image and use 0 instead of 100 in quality.
What's the problem exactly? Doesn't your code manage to open the file ? does it crash or have you just no error, but no output file?
By the way, you should call bitmap.recycle() at the end
It could help you harry
crop-image
BitmapFactory.Options optionsSignature = new BitmapFactory.Options();
final Bitmap bitmapSignature = BitmapFactory.decodeFile(
fileUriSignature.getPath(), optionsSignature);
Bitmap resizedSignature = Bitmap.createScaledBitmap(bitmapSignature, 256, 128, true);
signature.setImageBitmap(resizedSignature);
i am saving a captured image in sdcard by using following code
class SavePhotoTask extends AsyncTask<byte[], String, String> {
#Override
protected String doInBackground(byte[]... jpeg) {
File photo=new File(Environment.getExternalStorageDirectory(),"photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos=new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
}
catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
return(null);
}
}
but i am getting the image of resolution 1024*768 how can i change the resoultion of that image.
i am calling SavePhotoTask like this
Camera.PictureCallback photoCallback=new Camera.PictureCallback(){
public void onPictureTaken(byte[] data, Camera camera){
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
canvas.drawBitmap(itembmp,left,right,null);
image.setImageBitmap(mutableBitmap);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
mutableBitmap.compress(Bitmap.CompressFormat.PNG,100, stream);
byte[] byteArray = stream.toByteArray();
new SavePhotoTask().execute(byteArray);
Toast.makeText(PreviewDemo1.this,"Image Saved",Toast.LENGTH_LONG).show();
camera.startPreview();
inPreview=true;
}
};
thanks in advance
It is the jpeg passed to the doInBackground method that already has that resolution - you need to change whatever is calling this code.
If you can parse it to BitMap then you can use this:
private final int MAX_WIDTH = 400;
private final int MAX_HEIGHT = 400;
public Bitmap getResizedBitmap(Bitmap bm) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth;
float scaleHeight;
if (width < MAX_WIDTH && height < MAX_HEIGHT) {
return bm;
}
if (width > height) {
scaleWidth = ((float) MAX_WIDTH) / width;
scaleHeight = ((float) MAX_HEIGHT * height / width) / height;
} else {
scaleWidth = ((float) MAX_WIDTH * width / height) / width;
scaleHeight = ((float) MAX_HEIGHT) / height;
}
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
matrix, false);
return resizedBitmap;
}