inSampleSize is not working - android

In short, I can't resize my image file (475px in height) using inSampleSize. Code as below.
Image should be reduced to 237.5 px, after the code, isn't it? But it remains unchanged, exactly same as original dimension.
Anybody can help please.
File f = new File(context.getCacheDir(), "1223fdf");
URL imageUrl = new URL("http://example.com/file.jpg");
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(false);
String url = conn.getHeaderField("Location");
URL redirectURL = new URL(url);
URLConnection redirectConn = redirectURL.openConnection();
InputStream is=redirectConn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
final int REQUIRED_SIZE=200;
int height_tmp=o.outHeight; // This returns 475
int scale=1;
while(true){
if(height_tmp/2<REQUIRED_SIZE)
break;
height_tmp/=2;
scale*=2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale; //SCALE = 2 here (checked by printing in LogCat)
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
return bmp;
public class Utils {
public static void CopyStream(InputStream is, OutputStream os)
{
final int buffer_size=1024;
try
{
byte[] bytes=new byte[buffer_size];
for(;;)
{
int count=is.read(bytes, 0, buffer_size);
if(count==-1)
break;
os.write(bytes, 0, count);
}
}
catch(Exception ex){}
}
}

Related

Android create file from drawable

Is there any way to create file from image drawable to send it via MultypartEntity? I having error all the time.
fileUri = Uri.parse("android.resource://com.wellbread/drawable/placeholder_avatar.png");
mCurrentPhotoPath = fileUri.toString();
java.io.FileNotFoundException: android.resource:/com.wellbread/drawable/placeholder_avatar.png: open failed: ENOENT (No such file or directory)
08-25 12:01:53.134 3663-3684/? W/System.errīš• at libcore.io.IoBridge.open(IoBridge.java:456)
Try the following sample code:
Drawable drawable = getResources().getDrawable(R.drawable.ic_action_home);
if (drawable != null) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
final byte[] bitmapdata = stream.toByteArray();
String url = "http://10.0.2.2/api/fileupload";
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
// Add binary body
if (bitmapdata != null) {
ContentType contentType = ContentType.create("image/png");
String fileName = "ic_action_home.png";
builder.addBinaryBody("file", bitmapdata, contentType, fileName);
httpEntity = builder.build();
...
}
...
}
try this:
try
{
File f=new File("file name");
InputStream inputStream = getResources().openRawResource(id); // id drawable
OutputStream out=new FileOutputStream(f);
byte buf[]=new byte[1024];
int len;
while((len=inputStream.read(buf))>0)
out.write(buf,0,len);
out.close();
inputStream.close();
}
catch (IOException e){}
}
You can open an InputStream from your drawable resource using following code:
try
{
File f=new File("your file name");
//id is some like R.drawable.b_image
InputStream inputStream = getResources().openRawResource(id);
OutputStream out=new FileOutputStream(f);
byte buf[]=new byte[1024];
int len;
while((len=inputStream.read(buf))>0)
out.write(buf,0,len);
out.close();
inputStream.close();
}
catch (IOException e){}
}
You have to get Bitmap from drawable:
public static Bitmap decodeAndSetWidthHeight(Resources res, int resId, int reqWidth, int reqHeight){
Bitmap btm = BitmapHelper.decodeSampledBitmapFromResource(res, resId, reqWidth, reqHeight);
return decodeAndSetWidthHeight(btm, reqWidth, reqHeight);
}
Then you can create file from bitmap
public static File bitmapToFile(Bitmap bitmap){
File outFile = FileHelper.getImageFilePNG();
FileOutputStream out = null;
try {
out = new FileOutputStream(outFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return outFile;
}
UPDATE (sorry, forget to provide some methods):
public static File getImageFilePNG() {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/any name folder");
dir.mkdirs();
String fileName = String.format("%d.png", System.currentTimeMillis());
return new File(dir, fileName);
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
Log.d("ANT", "options.inSampleSize : " + options.inSampleSize);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static Bitmap decodeAndSetWidthHeight(Bitmap btm, int reqWidth, int reqHeight){
Matrix m = new Matrix();
RectF inRect = new RectF(0, 0, btm.getWidth(), btm.getHeight());
RectF outRect = new RectF(0, 0, reqWidth, reqHeight);
m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.FILL);
float[] values = new float[9];
m.getValues(values);
return Bitmap.createScaledBitmap(btm, (int) (btm.getWidth() * values[0]), (int) (btm.getHeight() * values[4]), true);
}

Get bitmap from input stream and resize

I want to get bitmap from a inputstream, then re-size it. But I am getting below error.
If I return without re-sizing, it works fine.
Can anybody help please?
LOGCAT:
01-07 01:38:33.412: D/skia(1307): --- SkImageDecoder::Factory returned null
CODE:
private Bitmap getBitmap(String url)
{
try {
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
conn.setDoInput(true);
conn.setInstanceFollowRedirects(true);
conn.connect();
InputStream is=conn.getInputStream();
//return BitmapFactory.decodeStream(is); // THIS WORKS FINE
bitmap = decodeFile(is);
is.close();
return bitmap;
} catch (Exception ex){
return null;
}
}
private Bitmap decodeFile(InputStream istream){
BufferedInputStream is = new BufferedInputStream(istream);
try {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is,null,o);
final int REQUIRED_SIZE=60;
int height_tmp=o.outHeight;
int scale=1;
while(true){
if(height_tmp/2<REQUIRED_SIZE)
break;
height_tmp/=2;
scale*=2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
Log.d("insample", "aa: "+scale);
return BitmapFactory.decodeStream(is, null, o2);
} catch (Exception e) {
Log.d("aaa","aa: "+e);
} finally{
try {
is.close();
} catch( IOException ignored ) {}
}
return null;
}
at
iv.setImageResource(resId);
resId is invalid value...
change it to
iv.setImageResource(R.drawable.ic_launcher);
and test the code

How to prevent out of memory exception while trying to convert input stream object into bitmap in android?

I had used following code to convert inputstream object into bitmap. But it returns "out of memory error", and BitmapFactory Options always returns Zero.
S3ObjectInputStream inputStreamReceiptObject = objectReceiptFromAmazonS3
.getObjectContent();
Bitmap bitmapImageFromAmazon = null;
try {
if (inputStreamReceiptObject != null){
BitmapFactory.Options o = new BitmapFactory.Options();
o.inSampleSize = 8;
o.inJustDecodeBounds = true;
bitmapImageFromAmazon = BitmapFactory.decodeStream(inputStreamReceiptObject,null,o); // o is always null
if(bitmapImageFromAmazon == null){
System.out.println("Bitmap null");
}
}
Advance Thanks for any help !
SOLUTION : ( Lot of thanks to Honourable Don and Honourable Akshat )
ByteArrayOutputStream baos = null ;
InputStream is1 = null,is2 = null;
try {
baos = new ByteArrayOutputStream();
// Fake code simulating the copy
// You can generally do better with nio if you need...
// And please, unlike me, do something about the Exceptions :D
byte[] buffer = new byte[1024];
int len;
while ((len = inputStreamReceiptObject.read(buffer)) > -1 ) {
baos.write(buffer, 0, len);
}
baos.flush();
// Open new InputStreams using the recorded bytes
// Can be repeated as many times as you wish
is1 = new ByteArrayInputStream(baos.toByteArray());
is2 = new ByteArrayInputStream(baos.toByteArray());
bitmapImageFromAmazon = getBitmapFromInputStream(is1,is2);
if(bitmapImageFromAmazon == null)
System.out.println("IMAGE NULL");
else
System.out.println("IMAGE NOT NULL");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
baos.close();
is1.close();
is2.close();
}
public Bitmap getBitmapFromInputStream(InputStream is1,InputStream is2) throws IOException {
Bitmap bitmap = null;
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is1,null,o);
//Find the correct scale value. It should be the power of 2.
int scale=1;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
bitmap = BitmapFactory.decodeStream(is2, null, o2);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
Why dont you try and scale the bitmap image down? Thats mostly the reason why your app showed OOM exception
BitmapFactory.Options o = new BitmapFactory.Options();
o.inScaled = false;
o.inJustDecodeBounds = true;
FileInputStream stream1 = new FileInputStream(f);
BitmapFactory.decodeStream(stream1, null, o);
stream1.close();
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70; //This is the max size of the bitmap in kilobytes
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
FileInputStream stream2 = new FileInputStream(f);
Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
stream2.close();
return bitmap;
The Out Of Memory error should be as it says: you do not have enough memory on your device to render the entire image. You need to ensure that the image you're downloading from S3 is not too big for the device.
To help you debug, try running downloading a smaller image to see if you are still receiving the OOM errors
URLConnection conn = new URL("http://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Victoria_Parade_postcard.jpg/120px-Victoria_Parade_postcard.jpg").openConnection();
InputStream stream = conn.getInputStream();
Bitmap image = BitmapFactory.decodeStream(stream, null, null);
The o you pass into decodeStream is null because of the OOM error (it must have gone out of scope when you examined it in the debugger).

Failed to decode bitmap from an image file

I am trying to download images from URL. The image type is PNG and the resolution is 400x400 pixels.
Here is the download code snippet.
Bitmap bitmap=null;
URL imageUrl = new URL(url);
conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream ins=conn.getInputStream();
os = new FileOutputStream(f);
Utilities.getUtilities().copyStream(ins, os);
os.flush();
Log.i(TAG_NAME, "file size : "+ f.length());
Log.i(TAG_NAME, "file exists in cache? " + f.exists());
bitmap = decodeFile(f);
return bitmap;
Here is the file writer.
public void copyStream(InputStream is, OutputStream os) {
final int buffer_size=1024;
try
{
byte[] bytes=new byte[buffer_size];
for(;;)
{
int count=is.read(bytes, 0, buffer_size);
if(count==-1)
break;
os.write(bytes, 0, count);
}
}
catch(Exception ex){
ex.printStackTrace();
}
}
And the decode method
private Bitmap decodeFile(File f){
//decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
try {
BitmapFactory.decodeStream(new FileInputStream(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
final int REQUIRED_SIZE = 400; //for testing, it is set to b a constant
System.out.println("REQUIRED_SIZE >>> " + REQUIRED_SIZE);
int width_tmp=o.outWidth, height_tmp=o.outHeight;
int scale=1;
while(true){
if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
break;
width_tmp/=2;
height_tmp/=2;
scale*=2;
}
//decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
//o2.inJustDecodeBounds = true;
o2.inPreferredConfig = Bitmap.Config.ARGB_8888;
o2.inSampleSize=scale; //scale is set off since android:src automatically scales the image to fit the screen
try {
return BitmapFactory.decodeStream(new FileInputStream(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
I can see that the file exists in the device. However, the decode stream is failing. I spent hours searching on the internet; tried almost everything, no success and almost my heads rolling.
Decode streams is causing the following error.
SkImageDecoder::Factory returned null
Do you find anything missing here?
EDIT:
Issue is now solved. The server was expecting cookie details which I failed to attach. Spent almost a day, beating around the bushes :-)
Thanks all for the valuable comments!
IMO, you may want to re-evaluate merits of httpurlconn vs native httpclient implementation. Android/google go for httpurlconn but, many opt to take greater control of low level details surrounding net protocol.
Here is sample async httpclient that wraps in bitmap handler. You can easily extend the sample method=processBitmapEntity() with your rules affecting bmp size.
Sample getbitmap url:
public int getBitmap(String mediaurl, int ctr){
Handler handler = new Handler() {
public void handleMessage(Message message) {
switch (message.what) {
case HttpConnection.DID_START: {
Log.d(TAG, "Starting connection...");
break;
}
case HttpConnection.DID_SUCCEED: {
//message obj is type bitmap
Log.d(TAG, "OK bmpARRAY " +message.arg1);
Bitmap response = (Bitmap) message.obj;
break;
}
case HttpConnection.DID_ERROR: {
Exception e = (Exception) message.obj;
e.printStackTrace();
Log.d(TAG, "Connection failed.");
break;
}
}
}
};
new HttpConnection(handler, PreferenceManager.getDefaultSharedPreferences(this), ctr).bitmap(mediaurl);
return -1;
And the bitmap handler in HttpConnection class that is part of the link sample above:
private void processBitmapEntity(HttpEntity entity) throws IOException {
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
Bitmap bm = BitmapFactory.decodeStream(bufHttpEntity.getContent());
handler.sendMessage(Message.obtain(handler, DID_SUCCEED, bm));
}
And a git project

How to receive a byte array and convert it to image in Android?

I have used:
InputStream in;
Bitmap bmp=BitmapFactory.decodeStream(in);
but the process waits for a long time and nothing happens. On the server side, i have the image converted into byte[].
I think this piece of code will be useful for you:
public Bitmap DownloadImage(String url)
{
HttpClient client = new DefaultHttpClient();
HttpResponse httpResponse;
Bitmap bmp = null;
try{
httpResponse = client.execute(new HttpGet(url));
responseCode = httpResponse.getStatusLine().getStatusCode();
HttpEntity entity = httpResponse.getEntity();
if (entity != null)
{
InputStream in = entity.getContent();
bmp = BitmapFactory.decodeStream(in);
in.close();
}
} catch (ClientProtocolException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
} catch (IOException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
}
return bmp;
}
Try this way to convert to bitmap.
try {
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn =
(HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is=conn.getInputStream();
InputStream is;
OutputStream os = new FileOutputStream(f);
bitmap = decodeFile(f);
return bitmap;
} catch (Exception ex){
ex.printStackTrace();
return null;
}
// decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
try {
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
}
return null;
}

Categories

Resources