Android: Compress a bitmap with few ram abuse - android

when I call
BitmapFactory.decodeFile(filepath);
I have an out of memory error because the file is too big.
How can I compress this file without abusing of the ram and without scaling it?
Please, help me =(
this is what i could do for now (i found this code here on stack)
bm = BitmapFactory.decodeFile(filepath);
File compressedFilePicture;
try {
compressedFilePicture = createImageFile();
FileOutputStream fOut = new FileOutputStream(compressedFilePicture);
bm.compress(CompressFormat.JPEG, COMPRESS_VALUE, fOut);
new File(filepath).delete();
filepath = compressedFilePicture.getAbsolutePath();
bm = BitmapFactory.decodeFile(filepath);
imageview.setImageBitmap(bm);
sc.string = filepath;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I need to load the bitmap on ram a slice a time.. any idea??

bm = BitmapFactory.decodeFile(filepath);
File compressedFilePicture;
try {
compressedFilePicture = createImageFile();
FileOutputStream fOut = new FileOutputStream(compressedFilePicture);
bm.compress(CompressFormat.JPEG, COMPRESS_VALUE, fOut);
new File(filepath).delete();
filepath = compressedFilePicture.getAbsolutePath();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; //u can use 2/4/8/16....ect
Uri uri = getImageUri(filepath);
InputStream in = in = contentResolver.openInputStream(uri);
bm = BitmapFactory.decodeStream(in, null, options);
imageview.setImageBitmap(bm);
sc.string = filepath;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Related

Retrofit upload image, FileNotFoundException, Content type uri

Trying to upload image as file using Retrofit, have uploaded files when path was of type file:// but now due to naugat , have changed the path Uri to Content:/ type, now when i convert this path to file and make retrofit Call, it gives FileNotFoundException
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"),photoFile);
this is the value of photoFile used above- file:/storage/emulated/0/Android/data/com.Bawa.Sketches/files/Pictures/JPEG_20161114_063716_-1561886067.jpg
USed setPic() method given in developer's site
private void setPic(ImageView sketchIv) {
InputStream input = null;
try {
input = getContentResolver().openInputStream(Uri.parse(mCurrentPhotoPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Get the dimensions of the View
int targetW = 300;
int targetH = 300;
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(input, null, bmOptions);
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
try {
input = getContentResolver().openInputStream(Uri.parse(mCurrentPhotoPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bmOptions);
sketchIv.setImageBitmap(bitmap);
compressImage(bitmap);
//showAlertDialog(bitmap);
}
called CompressImage() method to reduce size of the image and got the photoFile value in the method
private void compressImage(Bitmap lbitmap) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
File f = new File(Uri.parse(mCurrentPhotoPath).toString());
try {
f.createNewFile();
Bitmap bitmap = lbitmap;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos = null;
fos = new FileOutputStream(f);
fos.write(bitmapdata);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
}
photoFile = f;
Log.i("response","FILE : "+ f);
}
P.S. have read Commonsware's answer most of the places - If you get a content:// Uri, please consume it using a ContentResolver and methods like openInputStream() and openOutputStream().
do not have any idea how to implement this.
called CompressImage() method to reduce size of the image and got the photoFile value in the method
We discussed this previously.
File f = new File(Uri.parse(mCurrentPhotoPath).toString());
Uri.parse(mCurrentPhotoPath).toString() will give you mCurrentPhotoPath back, as parse() and toString() undo each other. And mCurrentPhotoPath is a string representation of a Uri, not a filesystem path.
So, modify compressImage() to use the same InputStream approach that you used in setPic().
check this code,Create a typed file using your image path. I think it will work.
TypedFile typedFile = new TypedFile("image/jpeg", new File(photoFile ));
or
if you are using retrofit version above 2 then you can you use following code.
RequestBody file = RequestBody.create(MediaType.parse("image/*"), photoFile );

How to take screen-shot of app screen in android?

I am developing an application in which I have to take screen-shot of app screen
right now I used below code it is not working. I am null bitmap image
Process sh = Runtime.getRuntime().exec("su", null,null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + "/sdcard/"+ "bs_score_img" +".png").getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();
String screenShot = Environment.getExternalStorageDirectory().toString()+"/bs_score_img.png";
Log.i("TAG:Score: screenShot path=", screenShot);
Bitmap bmp = BitmapFactory.decodeFile(new File(screenShot).getAbsolutePath());
try this :
Process sh = Runtime.getRuntime().exec("su", null,null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + "/sdcard/img.png").getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();
then read img.png as bitmap and convert it jpg as follows
Bitmap screen = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+
File.separator +"img.png");
//my code for saving
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
screen.compress(Bitmap.CompressFormat.JPEG, 15, bytes);
//you can create a new file name "test.jpg" in sdcard folder.
File f = new File(Environment.getExternalStorageDirectory()+ File.separator + "test.jpg");
f.createNewFile();
//write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
// remember close de FileOutput
fo.close();
Google has a library with which you can take screenshot without rooting, I tried that, But i am sure that it will eat out the memory as soon as possible.
Try http://code.google.com/p/android-screenshot-library/
or try this :
View v1 = L1.getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bm = v1.getDrawingCache();
BitmapDrawable bitmapDrawable = new BitmapDrawable(bm);
image = (ImageView) findViewById(R.id.screenshots);
image.setBackgroundDrawable(bitmapDrawable);
I found this code from another post:
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + ACCUWX.IMAGE_APPEND;
// create bitmap screen capture
Bitmap bitmap;
View v1 = mCurrentUrlMask.getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
OutputStream fout = null;
imageFile = new File(mPath);
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Let's say that you clicked on button
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Bitmap bitmap = takeScreenshot();
saveBitmap(bitmap);
}
});
After that you need this two methods
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
public Bitmap screenShot(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
just call this method with the view you want a snapshot of.. so if you want the whole screen just pass in you top most ViewGroup. if you want the System controls also just call:
you can try this
private Bitmap getScreen(){
mDecorView = getWindow().getDecorView();
runOnUiThread(new Runnable() {
public void run() {
mDecorView.invalidate();
mDecorView.post(this);
}
});
View v1 = mDecorView.getRootView();
System.out.println("Root View : "+v1);
v1.setDrawingCacheEnabled(true);
return v1.getDrawingCache();
}
here mDecorView is View .
Here how you can capture screen and save it in your storage
give permissions for creating file in external storage
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
And this is code for activity.
private void takeScreenshot() {
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
// create bitmap screen capture
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
openScreenshot(imageFile);
} catch (Throwable e) {
// Several error may come out with file handling or OOM
e.printStackTrace();
}
}
This is how you can capture the screen.

Sending bitmap image to next activity in android and converting it into string

I m not able to convert the bitmap into string and pass it to the JSON by send the intent.putExtra.....And on receiving it on Create method of next activity....
The Default is giving error and i have jpeg images ...
How to fix this problem....
Intent Intent inn=getIntent()
bitmap = (Bitmap) inn.getParcelableExtra("bmp_img");
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
byte [] b=baos.toByteArray();
String temp=Base64.encodeToString(b, Base64.DEFAULT);
public String imageCompression(String image) {
// to compress image
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
Bitmap b = BitmapFactory.decodeFile(image, bmpFactoryOptions);
Bitmap out = Bitmap.createScaledBitmap(b, 300, 300, false);
String[] bits = image.split("/");
String lastOne = bits[bits.length - 1];
File imageFile = null;
File imagesFolder = new File(Environment.getExternalStorageDirectory(),
"CompressedImages");
if (imagesFolder.isDirectory()) {
imageFile = new File(imagesFolder, lastOne);
FileOutputStream fOut;
try {
fOut = new FileOutputStream(imageFile);
out.compress(Bitmap.CompressFormat.JPEG, 90, fOut);
fOut.flush();
fOut.close();
b.recycle();
out.recycle();
} catch (Exception e) {
e.printStackTrace();
}
} else {
imagesFolder.mkdirs();
imageFile = new File(imagesFolder, lastOne);
FileOutputStream fOut;
try {
fOut = new FileOutputStream(imageFile);
out.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
b.recycle();
out.recycle();
} catch (Exception e) {
e.printStackTrace();
}
}
File file = new File(imageFile.getPath());
byte imageData[] = new byte[(int) file.length()];
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e3) {
e3.printStackTrace();
}
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
BufferedInputStream bis = new BufferedInputStream(fis);
try {
bis.read(imageData, 0, imageData.length);
} catch (IOException e1) {
e1.printStackTrace();
}
imageDataString = Base64.encodeToString(imageData, 0);
return imageDataString;
}
Use this methord and for intent passing pass just as String ......
i assume u are navigate from TO Activity A and B in sort of A->B
in A
Uri imageUri = Uri.parse("android.resource://your.package/drawable/fileName");
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/png");
intent.putExtra(Intent.EXTRA_STREAM, imageUri);
startActivity(intent)
and in B
Intent intent = this.getIntent();
(Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM);

Fit just taken photo into imagebutton

I have an ImageButton, when I press it I can take a picture with my phone. When I take the picture the ImageButtons gets the picture as its source. But the problem is, is that the image doesn't scale down to the dimensions of the ImageButton. It just shows a part of the image in the Imagebutton instead of scaling down. After doing a bit of research I saw you have to use a draw 9 patch. But that is not possible in this case, because the image aren't in my resources, they are made by the user itself.
Can someone help me with this?
My code:
if (requestCode == REQUEST_CAMERA) {
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
try {
Bitmap bm;
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
bm = BitmapFactory.decodeFile(f.getAbsolutePath(),btmapOptions);
// bm = Bitmap.createScaledBitmap(bm, 70, 70, true);
btnImg.setImageBitmap(bm);
String path = android.os.Environment.getExternalStorageDirectory() + File.separator + "Phoenix" + File.separator + "default";
f.delete();
OutputStream fOut = null;
File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
try {
fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
else if (requestCode == SELECT_FILE) {
Uri selectedImageUri = data.getData();
String tempPath = getPath(selectedImageUri, MainActivity.this);
Bitmap bm;
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
bm = BitmapFactory.decodeFile(tempPath, btmapOptions);
btnImg.setImageBitmap(bm);
}
Use ImageView's method setScaleType. Pass ScaleType.CENTER_INSIDE as parameter.
btnImg.setImageBitmap(bm);
btnImg.setScaleType(ScaleType.CENTER_INSIDE);

Scrambled images after calling Camera.takepicture() on HTC Incredible

Taking picture by calling Camera.takepicture() on HTC Incredible results in getting scrambled images. This problem does not appear on any other devices I´ve tested my application(Galaxy SII, Galaxy S, Nexus S). I haven´t been able to find the solution on my own as of yet...
Image linked: http://i.stack.imgur.com/j4VE8.jpg (need more reputation to post it)
This is how I save my imageData:
static boolean StoreByteImage(Context mContext, byte[] imageData,
int quality, String expName) {
File sdImageMainDirectory = new File("/sdcard");
FileOutputStream fileOutputStream = null;
//String nameFile;
try {
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap myImage = BitmapFactory.decodeByteArray(imageData, 0,
imageData.length,options);
fileOutputStream = new FileOutputStream(
sdImageMainDirectory.toString() +"/CapturedQRCode.jpg");
BufferedOutputStream bos = new BufferedOutputStream(
fileOutputStream);
myImage.compress(CompressFormat.PNG, quality, bos);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
Anyone got a hint?

Categories

Resources