How to deal with OutOfMemory Exception - android

I'm using Volley library in my project but I have problem with OutOfMemory Exception. In my application I'm downloading thumbs and full size images from server via NetworkImageView using setImageUrl method. I'm using BitmapLruCache:
public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache {
public static int getDefaultLruCacheSize() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
public BitmapLruCache() {
this(getDefaultLruCacheSize());
}
public BitmapLruCache(int sizeInKiloBytes) {
super(sizeInKiloBytes);
}
#Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
#Override
public Bitmap getBitmap(String url) {
return get(url);
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
I'm getting OutOfMemoryException on HTC Desire (Android 2.2.2). How can I deal with this exception? Is something wrong I'm doing?
Edit
This exception I got during monkey test:
java.lang.OutOfMemoryError at
com.android.volley.toolbox.ByteArrayPool.getBuf(ByteArrayPool.java:101)
at
com.android.volley.toolbox.PoolingByteArrayOutputStream.expand(PoolingByteArrayOutputStream.java:76)
at
com.android.volley.toolbox.PoolingByteArrayOutputStream.write(PoolingByteArrayOutputStream.java:84)
at
com.android.volley.toolbox.BasicNetwork.entityToBytes(BasicNetwork.java:213)
at
com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:104)
at
com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)
#Sipka - it doesn't solve my problem
#Muhammad Babar - Volley library handles all network/bitmap/cache operations so I need solution to fix OutOfMemory exception caused by Volley.

Use this code to create Bitmap in a thread that will help you
Bitmap bitmap = null;
HttpResponse response = null;
InputStream instream = null;
try {
File file = new File(Environment.getExternalStorageDirectory()
.toString(), floderName);
String s = file.getAbsolutePath();
f = new File(s);
if (!f.exists()) {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(new URL(url[0]).toURI());
response = client.execute(request);
if (response.getStatusLine().getStatusCode() != 200) {
return null;
}
// BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(
// response.getEntity());
instream = response.getEntity().getContent();
OutputStream os = new FileOutputStream(f);
Globals.CopyStream(instream, os);
os.close();
instream.close();
}
FileInputStream fs = null;
try {
fs = new FileInputStream(f);
} catch (FileNotFoundException e) {
// TODO do something intelligent
e.printStackTrace();
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inDither = false; // Disable Dithering mode
o2.inPurgeable = true; // Tell to gc that whether it needs free
// memory, the Bitmap can be cleared
o2.inInputShareable = true; // Which kind of reference will be used
// to recover the Bitmap data after
// being clear, when it will be used in
// the future
o2.inTempStorage = new byte[32 * 1024];
o2.inSampleSize = 1;
bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, o2);
bit = bitmap;
// bit.compress(Bitmap.CompressFormat.JPEG, 90, null);
newsFeed.setBitmap(bit);
// Data.globelCoverIcon = bit;
// OutputStream os = new FileOutputStream(f);
} catch (Exception ex) {
ex.printStackTrace();
}
public class Globals {
private static final int JPEG_EOI_1 = 0xFF;
private static final int JPEG_EOI_2 = 0xD9;
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) {
Log.e("App", ex.getMessage(), ex);
}
}
}

Related

Copy inputStream to file and read from it

I want to copy the content of an input-stream which is actually a bitmap to a file-output-stream. After that I want to pass the content of the file-output-stream to BitmapFactory.decodeStream. The result is that I am getting damaged images! my code for these things is the below.
private void copyInStreamToFile(InputStream is) {
byte buf[] = new byte[1024];
int len;
FileOutputStream fos;
try {
fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
while ((len = is.read(buf)) > 0)
fos.write(buf, 0, len);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static FileInputStream getStream() throws FileNotFoundException {
return context.openFileInput(FILENAME);
}
I am calling this inside the download method
Bitmap downloadBitmap(String url) {
final int IO_BUFFER_SIZE = 4 * 1024;
// AndroidHttpClient is not allowed to be used from the main thread
final HttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode
+ " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
copyInStreamToFile(new FlushedInputStream(inputStream));
DeviceProperties device = new DeviceProperties(activity);
return decodeBitampFromResource(device.getDeviceHeight(),
device.getDeviceWidth());
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
and the last method which makes the decoding is this:
public static Bitmap decodeBitampFromResource(int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
FileInputStream fis;
InputStream is;
Bitmap bitmap = null;
// kanonika tha vriskei to megethos tis photo alla kapoio problima
// iparxei me ton sixronismo
try {
fis = getStream();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(fis, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
fis.close();
fis = getStream();
bitmap = BitmapFactory.decodeStream(fis, null, options);
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap;
}
Do I have to clear the content of the file-output-stream? As I know from android developers openFileOutput opens the file and override it's content or creates it if it doesn't exist.

BitmapFactory.decodeStream returns null, when downloading a image form web

I'm trying to download a image from a URL, using the Google Example Page. I've read when I use a InputStream in the BitmapFactory.decodeStream method, I can't use twice. I'm trying to do that, but it doesn't work 'cause it returns null in the decoded image, and I don't know what I can do.
This is my code:
This part is in a doInBackground method in a AsyncTask class
Bitmap bitmapImage;
URL imageUrl = null;
try {
imageUrl = new URL(url[0]);
HttpGet httpRequest = null;
httpRequest = new HttpGet(imageUrl.toURI());
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
InputStream instream = bufHttpEntity.getContent();
bitmapImage = CommonMethods.decodeSampledBitmapFromResource(instream, thumb_width, thumb_width);
instream.close();
return bitmapImage;
} catch (URISyntaxException e) {
e.printStackTrace();
return null;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
public static Bitmap decodeSampledBitmapFromResource(InputStream instream,
int reqWidth, int reqHeight) throws IOException {
//Copy instream for decode twice
ByteArrayOutputStream out = new ByteArrayOutputStream();
copy(instream,out);
ByteArrayInputStream instream2 = new ByteArrayInputStream(out.toByteArray());
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(instream, null, options);
instream2.close();
options.inJustDecodeBounds = false;
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
return BitmapFactory.decodeStream(instream, null, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
//Copy instream method
public static void copy(InputStream input, OutputStream output) throws IOException{
byte[] buffer = new byte[Constants.IO_BUFFER_SIZE];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
}
BitmapFactory.decodeStream returns null because the inputstream is used twice, I've not tried your code, but it seams OK, or maybe I'm wrong.
Anyway, I've a better solution. Just use BufferedInputStream to wrap the inputStream, and before your second read, call "reset" first. Note ordinary inputStreams donnot support "reset", you may call it but nothing will happen.
My code:
public static Bitmap decodeSampledBitmapFromStream(InputStream inputStream,
int reqWidth, int reqHeight)
throws IOException {
if (!widthHeightCheck(reqWidth, reqHeight))
return BitmapFactory.decodeStream(inputStream);
// First decode with inJustDecodeBounds=true to check dimensions
if (!(inputStream instanceof BufferedInputStream)) {
inputStream = new BufferedInputStream(inputStream);
}
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Rect rect = new Rect(-1, -1, -1, -1);
BitmapFactory.decodeStream(inputStream, rect, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
inputStream.reset();
return BitmapFactory.decodeStream(inputStream, rect, options);
}
I think you can achieve this by wrapping the stream you get from the httpEntity in a custom WrappedStream. This WrappedStream will feed a second input stream while reading the original stream. (this is done with PipedStream)
After getting the image size with this code :
options.inJustDecodeBounds = true;
WrappedStream wrappedStream = new WrappedStream(instream);
BitmapFactory.decodeStream(wrappedStream, null, options);
You can call
InputStream reReadStream = wrappedStream.getReReadStream();
options.inJustDecodeBounds = false;
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
return BitmapFactory.decodeStream(reReadStream, null, options);
And finally, here is the implementation of WrappedStream (it simply delegates all calls to the wrapped inputStream, and writes all bytes that are read (or skipped) in a pipedOutputStream)
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/** Simple class wrapping an InputStream and feeding a secondary InputStream
* to re-read the data that was originally available in the inputStream.
**/
public class WrappedStream extends InputStream {
private InputStream urlStream;
private PipedOutputStream pipedStream;
public WrappedStream(InputStream urlStream) {
this.urlStream = urlStream;
this.pipedStream = new PipedOutputStream();
}
/**
* return a fresh InputStream to re-read the data
*/
public InputStream getReReadStream() throws IOException {
return new PipedInputStream(pipedStream);
}
#Override
public int available() throws IOException {
return urlStream.available();
}
#Override
public void close() throws IOException {
urlStream.close();
}
#Override
public void mark(int readlimit) {
urlStream.mark(readlimit);
}
#Override
public boolean markSupported() {
return urlStream.markSupported();
}
#Override
public int read() throws IOException {
int b = urlStream.read();
pipedStream.write(b);
return b;
}
#Override
public int read(byte[] buffer) throws IOException {
int l = urlStream.read(buffer);
pipedStream.write(buffer);
return l;
}
#Override
public int read(byte[] buffer, int offset, int length) throws IOException {
int l = urlStream.read(buffer, offset, length);
pipedStream.write(buffer, offset, length);
return l;
}
#Override
public void reset() throws IOException {
urlStream.reset();
}
#Override
//bytes skipped must available on the re-read stream so we read and write them.
public long skip(long byteCount) throws IOException {
long bytesToSkip = byteCount;
long skippedBytes = 0;
//ugly trick required to not loosing bytes if we ever skip more than Integer.MAX_VALUE bytes
while(bytesToSkip>Integer.MAX_VALUE){
_skip(Integer.MAX_VALUE);
bytesToSkip -=Integer.MAX_VALUE;
skippedBytes +=Integer.MAX_VALUE;
}
byte[] b = new byte[(int)bytesToSkip];
skippedBytes += read(b);
return skippedBytes;
}
private int _skip(int byteCount) throws IOException {
byte[] b = new byte[(int)byteCount];
return read(b);
}
}
Please note that I didn't test this code. This is just to give you some ideas on how to solve your problem.
Another point: even if this code never create a huge bitmap, the whole stream will be kept in memory until the scaled Bitmap is build.
Found the code which will work for you
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
BitmapFactory.Options options = new BitmapFactory.Options();
//options.inSampleSize = 2;
final Bitmap bitmap = BitmapFactory
.decodeStream(inputStream, null, options);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
Please replace the proper variable and if you wanted to scale the image you can scale it after getting the bitmap.
here is the method to download bitmap from server with less code you can fulfill your requirement
Bitmap downloadBitmap(String url)
{
Bitmap image = null;
InputStream in = null;
try
{
in = new java.net.URL(url).openStream();
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 2;
image = BitmapFactory.decodeStream(new FlushedInputStream(in),null,opts);
in.close();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return image;
}
in the above code we use
opts.inSampleSize = 2;
it means the bitmap will be reduced to half size of its original size to avoid memory exception we have to do this if we are loading lot of images
some other class used in it
static class FlushedInputStream extends FilterInputStream
{
public FlushedInputStream( InputStream inputStream )
{
super(inputStream);
}
#Override
public long skip(long n) throws IOException
{
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n)
{
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L)
{
int byte1 = read();
if (byte1 < 0)
{
break; // we reached EOF
}
else
{
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
Please Use below code for download and display image into imageview.
public class image extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Bitmap bitmap = DownloadImage("http://www.gophoto.it/view.php?i=http://1.bp.blogspot.com/-2LTvCCufBKc/T3L3KgcTj2I/AAAAAAAABbQ/Ki60e1LU9sE/s1600/Sachin%2BTendulkar.png");
ImageView img = (ImageView) findViewById(R.id.img);
img.setImageBitmap(bitmap);
}
private InputStream OpenHttpConnection(String urlString) throws IOException {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
} catch (Exception ex) {
throw new IOException("Error connecting");
}
return in;
}
private Bitmap DownloadImage(String URL) {
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return bitmap;
}
}

How to send multiple images to server using MultipartEntity from android

I am sending Images and Text to a PHP webservice using the following code.
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(URL);
MultipartEntity entity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 75, bos);
byte[] data = bos.toByteArray();
entity.addPart("files[]",
new ByteArrayBody(data, "myImage.jpg"));
entity.addPart("message0", new StringBody(caption.getText()
.toString()));
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost,
localContext);
BufferedReader reader = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
String sResponse = reader.readLine();
return sResponse;
} catch (Exception e) {
if (dialog.isShowing())
dialog.dismiss();
Toast.makeText(ImageUpload.this, e.getMessage(),
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
return null;
}
}
It works perfectly. But this is only for one image. I want to send 5 images.
Example: Image1 - Text1
Image2 - Text2 etc..
So I am confused about how to store 5 images one by one and then on button click, send these images and text associated with them to the server.
I am getting images from the phone's camera.
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"),
PICK_IMAGE);
public void onActivityResult_photo(int requestCode, int resultCode,
Intent data) {
// TODO Auto-generated method stub
if (resultCode == RESULT_OK) {
if (data != null) {
mImageCaptureUri = data.getData();
display(mImageCaptureUri);
} else {
Toast.makeText(CustomTabActivity.mTabHost.getContext(),
"No photo selected..", Toast.LENGTH_SHORT).show();
}
}
}
private String display(Uri mImageCaptureUri2) {
// TODO Auto-generated method stub
String base64string = null;
try {
if (mImageCaptureUri2 != null) {
System.gc();
selectedImagePath = getPath(mImageCaptureUri2);
File filenew = new File(selectedImagePath);
int file_size = Integer.parseInt(String.valueOf(filenew
.length() / 1024));
if (file_size <= 10000) {
PD1 = ProgressDialog.show(
CustomTabActivity.mTabHost.getContext(), "",
"Loading...");
Handler refresh = new Handler(Looper.getMainLooper());
refresh.post(new Runnable() {
public void run() {
PD1.setCancelable(true);
Bitmap newbitmap;
newbitmap = decodeFile(selectedImagePath);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
newbitmap.compress(Bitmap.CompressFormat.PNG, 50,
bs);
img.setVisibility(View.VISIBLE);
img.setImageBitmap(newbitmap);
byte[] abc = bitmapToByteArray(newbitmap);
if (txt_phototext.getText().toString().equals("")) {
submit.put(abc, "");
} else {
submit.put(abc, txt_phototext.getText()
.toString());
// executeMultipartPost();
}
PD1.dismiss();
}
});
} else {
AlertDialog.Builder alertbox = new AlertDialog.Builder(
CustomTabActivity.mTabHost.getContext());
alertbox.setMessage("Take Image Size Less than 10 MB");
alertbox.setNeutralButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0,
int arg1) {
finish();
}
});
alertbox.show();
}
} else {
System.out.println("===============NULL========");
}
} catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
}
return base64string;
}
static Bitmap decodeFile(String str) {
try {
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(str), 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++;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(str), null,
o2);
} catch (FileNotFoundException e) {
}
return null;
}
public static byte[] bitmapToByteArray(Bitmap bitmap) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0 /* ignored for PNG */, bos);
byte[] bitmapdata = bos.toByteArray();
return bitmapdata;
}
And make sure that your directory or folder in server is Executable, Writable and Readable. I had this as the major problem. This is called 777 permission.. Believe me, this is as important as other things to consider.
For full detail please have a look on my post Click here
its quite difficult to send multiple images to server using MultipartEntity. I did search for this but didn't find any right solution then i made my own way to send multiple images to server
, here i send array of selected paths to asynctask and in asynctask i sent images to server
Calling Asysnctask Function-
new Upload_Multiple.excute(Array_of_Path[]))
Private class Upload_Multiple_img extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
protected String doInBackground(String... paths_array) {
String data = "";
for (int i = 0; i < paths_array.length; i++) {
// get_Picture_bitmap() returns bitmap by passing path of image
// get_Picture_bitmap() is mentioned below.
Bitmap bitmap = get_Picture_bitmap(paths_array[i]);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
InputStream in = new ByteArrayInputStream(stream.toByteArray()); // convert
DefaultHttpClient httpclient = new DefaultHttpClient();
String server_funtion_url="...serveraddres"+funtion_at_server"";
HttpPost httppost = new HttpPost(server_funtion_url); // server
MultipartEntity reqEntity = new MultipartEntity();
obj_SP = ImagePicker.this.getSharedPreferences("Eperty", 0);
String id_prop = obj_SP.getString("new_prop_id", "");
String Image_Name =
+ String.valueOf(System.currentTimeMillis()) + ".jpg";
// image is a key which is used at server end to get this
reqEntity.addPart("image", Image_Name, in);
httppost.setEntity(reqEntity);
HttpResponse response = null;
try {
response = httpclient.execute(httppost);
data = EntityUtils.toString(response.getEntity());
System.out.println("FFFF== " + data);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return data;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
ConstantData.ToastAlert(ImagePicker.this,
"Images Uploaded successfully");
}
}
//);
For compressing the images and getting bitmap for i made below funtion*
public Bitmap get_Picture_bitmap(String imagePath) {
long size_file = getFileSize(new File(imagePath));
size_file = (size_file) / 1000;// in Kb now
int ample_size = 1;
if (size_file <= 250) {
System.out.println("SSSSS1111= " + size_file);
ample_size = 2;
} else if (size_file > 251 && size_file < 1500) {
System.out.println("SSSSS2222= " + size_file);
ample_size = 4;
} else if (size_file >= 1500 && size_file < 3000) {
System.out.println("SSSSS3333= " + size_file);
ample_size = 8;
} else if (size_file >= 3000 && size_file <= 4500) {
System.out.println("SSSSS4444= " + size_file);
ample_size = 12;
} else if (size_file >= 4500) {
System.out.println("SSSSS4444= " + size_file);
ample_size = 16;
}
Bitmap bitmap = null;
BitmapFactory.Options bitoption = new BitmapFactory.Options();
bitoption.inSampleSize = ample_size;
Bitmap bitmapPhoto = BitmapFactory.decodeFile(imagePath, bitoption);
ExifInterface exif = null;
try {
exif = new ExifInterface(imagePath);
} catch (IOException e) {
// Auto-generated catch block
e.printStackTrace();
}
int orientation = exif
.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Matrix matrix = new Matrix();
if ((orientation == 3)) {
matrix.postRotate(180);
bitmap = Bitmap.createBitmap(bitmapPhoto, 0, 0,
bitmapPhoto.getWidth(), bitmapPhoto.getHeight(), matrix,
true);
} else if (orientation == 6) {
matrix.postRotate(90);
bitmap = Bitmap.createBitmap(bitmapPhoto, 0, 0,
bitmapPhoto.getWidth(), bitmapPhoto.getHeight(), matrix,
true);
} else if (orientation == 8) {
matrix.postRotate(270);
bitmap = Bitmap.createBitmap(bitmapPhoto, 0, 0,
bitmapPhoto.getWidth(), bitmapPhoto.getHeight(), matrix,
true);
} else {
matrix.postRotate(0);
bitmap = Bitmap.createBitmap(bitmapPhoto, 0, 0,
bitmapPhoto.getWidth(), bitmapPhoto.getHeight(), matrix,
true);
}
return bitmap;
}
**
Server end Code *
$target_dir = "../webadmin/user_image/";
$target_dir = $target_dir . basename($_FILES["user_img"]["name"]);
if(move_uploaded_file($_FILES["image"]["tmp_name"], $target_dir))
{
$msg = "The file ". basename($result[0]). " has been uploaded.";
$send_arr['success'] = 1;
$send_arr['message'] = $msg;
echo json_encode($send_arr);
}
else
{
$msg = "Sorry, there was an error uploading your file.";
$send_arr['success'] = 0;
$send_arr['message'] = $msg;
echo json_encode($send_arr);
}
Why you can't just create array of json object of your images to base64 and post to server and at your server api read those images convert to byte and use as image.
Check my answe and try to implement.
In Android how to post data to webservice which is created in WCF?
And the images you are getting from camera store them in uri in sdcard and letter read them. You can assign image name sequntialy. And read them from uri.
Try increasing the post_max_size of your php.ini file in WAMP server
Please find the below method...here i m sending mutiple image file using AQUERY. The best lib to perform all background network related task.(Like AJAX).
https://code.google.com/p/android-query/
public void uploadImageFile( String filePath,
String message) {
Context context = ApplicationContextProvider.getContext();
String url = SERVER_URL + "/user/uploadImageFile";
try {
Toast.makeText(context, "Uploading...", Toast.LENGTH_SHORT)
.show();
String compressedFile = CommonUtilities.compressImage(filePath,
context);
Map<String, Object> params = new HashMap<String, Object>();
File imageFile = new File(compressedFile);
byte[] imageBytes1 = FileUtils.readFileToByteArray(imageFile);
params.put("imageBytes", imageBytes1);
params.put("message",URLEncoder.encode(message, "UTF-8"));
AQuery aq = new AQuery(context);
aq.ajax(url, params, JSONObject.class,
new AjaxCallback<JSONObject>() {
#Override
public void callback(String url, JSONObject json,
AjaxStatus status) {
Toast.makeText(
ApplicationContextProvider.getContext(),
"Uploaded successfully",
Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}

BitmapFactory.decodeStream cannot decode png type from ftp

What was my mistake? How I show png from FTP?
I'm newby for android and try to show image from difference connection/source.
Then I already show image which load from drawable and HTTP.
Now, I'm try to show from FTP, I get message "--- decoder->decode returned false" when I use..BitmapFactory.decodeStream(ins, null, options);
Then I found solution..
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
#Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int b = read();
if (b < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
Then it can load/decode file type "Jpeg, jpg", there are show completely.
But log cat say "--- decoder->decode returned false" when bitmap load file type "PNG" again.
Thank for advice...
ImageView bmImage = (ImageView) findViewById(R.id.faceImageView);
BitmapFactory.Options bmOptions;
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1;
Bitmap bm = LoadImage(image_URL, bmOptions);
bmImage.setImageBitmap(bm);
...
private Bitmap LoadImage(String URL, BitmapFactory.Options options) {
Bitmap bitmap = null;
InputStream in = null;
FlushedInputStream fIns = null;
try {
if (isFTP) {
in = downloadFile("");
if (remoteFile.toLowerCase().contains(".png")) {
fIns = new FlushedInputStream(in);
bitmap = BitmapFactory.decodeStream(fIns, null, options);
// byte[] bMapArray = new byte[buf.available()];
// buf.read(bMapArray);
// bitmap = BitmapFactory.decodeByteArray(bMapArray, 0,
// bMapArray.length);
} else {
fIns = new FlushedInputStream(in);
bitmap = BitmapFactory.decodeStream(fIns);
}
} else { // HTTP
in = OpenHttpConnection(URL);
fIns = new FlushedInputStream(in);
bitmap = BitmapFactory.decodeStream(fIns);
}
in.close();
} catch (IOException e1) {
}
return bitmap;
}
public synchronized InputStream downloadFile(String localfilename) {
InputStream inputStream = null;
String user = "aaa";
String pass = "8888";
String host = "xxx.xxx.xxx.xxx";
try {
FTPClient mFTPClient = new FTPClient();
mFTPClient.connect(host);
mFTPClient.login(user, pass);
mFTPClient.enterLocalPassiveMode();
mFTPClient.changeWorkingDirectory("/DroidPic");
String[] aa = mFTPClient.listNames();
String strTmp = "";
do {
strTmp = aa[(new Random()).nextInt(aa.length)];
} while (remoteFile == strTmp);
remoteFile = strTmp;
inputStream = mFTPClient.retrieveFileStream(remoteFile);
} catch (Exception ex) {
Toast.makeText(this, "Err:" + ex.getMessage(), Toast.LENGTH_LONG)
.show();
}
return inputStream;
}

inputstream.read has no response when downloading large image(size > 300K)

Hi guys. I have a problem when downloading large size images.It's very strange, while read bytes from stream always no response.
My code is as follows, any suggestion is welcome.
public class ImageTestActivity extends Activity {
public static final int IMAGE_BUFFER_SIZE = 8*1024;
public static final int MAX_REQUEST_WIDTH = 480;
public static final int MAX_REQUEST_HEIGHT = 480;
private static final String TAG = ImageTestActivity.class.getSimpleName();
private static final int HTTP_CONNECT_TIMEOUT = 10000;
private static final int CONTENT_IMAGE_OFFSET = 80;
private Display mDisplay = null;
private ImageView mContentPic = null;
private Bitmap mContentPicBitmap = null;
private RefreshAsyncTask mRefreshTask = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mContentPic = (ImageView)findViewById(R.id.wimessage_content_picture);
mDisplay = getWindowManager().getDefaultDisplay();
mRefreshTask = new RefreshAsyncTask();
mRefreshTask.execute("http://218.240.46.38/img/201206/28/-980416187.jpeg");
}
private void initImageSetting(Bitmap bm) {
if (bm == null) {
return;
}
int scrWidth = mDisplay.getWidth();
int scrHeight = mDisplay.getHeight();
int imageHeight = bm.getHeight();
int imageWidth = bm.getWidth();
/*if (imageHeight*3 < imageWidth*2) {
* It is very strange, when the picture aspect ratio less than 3:2,
* execute the following code will cause the picture is not displayed
*
return;
}*/
mContentPic.setAdjustViewBounds(true);
mContentPic.setMaxWidth(scrWidth - CONTENT_IMAGE_OFFSET);
if ((imageWidth <= scrWidth - CONTENT_IMAGE_OFFSET) || (imageHeight < scrHeight)) {
mContentPic.setMaxHeight(imageHeight);
} else {
mContentPic.setMaxHeight((int)((float)imageHeight * (scrWidth - CONTENT_IMAGE_OFFSET) / imageWidth));
}
}
public static byte[] getBytes(BufferedInputStream inStream) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
BufferedOutputStream out = new BufferedOutputStream(outStream, IMAGE_BUFFER_SIZE);
byte[] buffer = new byte[IMAGE_BUFFER_SIZE];
int len = inStream.read(buffer);
Log.i(TAG, "---start---");
while (len != -1) {
Log.i(TAG, ((Integer)len).toString());
try {
out.write(buffer, 0, len);
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
len = inStream.read(buffer);
}
Log.i(TAG, "---end---");
out.flush();
out.close();
inStream.close();
return outStream.toByteArray();
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
// This offers some additional logic in case the image has a strange
// aspect ratio. For example, a panorama may have a much larger
// width than height. In these cases the total pixels might still
// end up being too large to fit comfortably in memory, so we should
// be more aggressive with sample down the image (=larger
// inSampleSize).
final float totalPixels = width * height;
// Anything more than 2x the requested pixels we'll sample down
// further.
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
}
return inSampleSize;
}
public static Bitmap loadImageFromURL(String urlPath) {
try {
URL url = new URL(urlPath);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(HTTP_CONNECT_TIMEOUT);
int rspCode = connection.getResponseCode();
if (rspCode == HttpStatus.SC_OK) {
//InputStream in = connection.getInputStream();
Bitmap bitmap = null;
BufferedInputStream in = new BufferedInputStream(url.openStream(), IMAGE_BUFFER_SIZE);
byte[] data = getBytes(in);
in.close();
if (data != null) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inSampleSize = calculateInSampleSize(options, MAX_REQUEST_WIDTH, MAX_REQUEST_HEIGHT);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "data == null");
}
connection.disconnect();
return bitmap;
} else {
connection.disconnect();
Log.i(TAG, "rspCode = " + rspCode);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private class RefreshAsyncTask extends AsyncTask<String, Boolean, Boolean> {
#Override
protected Boolean doInBackground(String... arg0) {
mContentPicBitmap = loadImageFromURL(arg0[0]);
return true;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (mContentPicBitmap != null) {
initImageSetting(mContentPicBitmap);
mContentPic.setImageBitmap(mContentPicBitmap);
}
}
}
}
try this i have try with ur links it show me an image in imageview
BitmapFactory.Options bmOptions;
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1;
bm = LoadImage("http://218.240.46.38/img/201206/28/-980416187.jpeg", bmOptions);
imageview.setImageBitmap(bm);
where methos LoadImage is as given below
private Bitmap LoadImage(String URL, BitmapFactory.Options options){
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in, null, options);
in.close();
} catch (IOException e1) {
}
return bitmap;
}
private InputStream OpenHttpConnection(String strURL) throws IOException {
InputStream inputStream = null;
URL url = new URL(strURL);
URLConnection conn = url.openConnection();
try{
HttpURLConnection httpConn = (HttpURLConnection)conn;
httpConn.setRequestMethod("GET");
httpConn.connect();
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
inputStream = httpConn.getInputStream();
}
} catch (Exception ex){
}
return inputStream;
}
updated:
use connection.getInputStream() replace url.openStream():
BufferedInputStream in = new BufferedInputStream(connection.getInputStream(), IMAGE_BUFFER_SIZE);
and your getBytes method try this:
public static byte[] getBytes(BufferedInputStream inStream) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(IMAGE_BUFFER_SIZE);
byte[] buffer = new byte[IMAGE_BUFFER_SIZE];
int len = 0;
Log.i(TAG, "---start---");
while ((len = inStream.read(buffer)) != -1) {
out.write(buffer, 0, len);
Log.i(TAG, "readed:" + len);
}
Log.i(TAG, "---end---");
out.flush();
inStream.close();
return out.toByteArray();
}
and last dont forget add permission:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Categories

Resources