简体   繁体   中英

Android Image Upload working for camera but not gallery

I am trying to get an image and upload it. This is always working for Camera but not working for images from gallery. It is failing with HTTP status of 422 and always succeeds for camera images with status code 201.

Here is my Image capture code:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Bitmap takenPictureData;

switch (imageUploadMethod) {
case Constants.SELECT_CAMERA:

try {
if (requestCode == Constants.SELECT_CAMERA && data != null) {
Bundle extras = data.getExtras();
if (extras!= null && extras.containsKey("data")) {
    takenPictureData = (Bitmap) extras.get("data");
    ImageView imageView = (ImageView) getActivity().findViewById(R.id.fragment_add_retailer_img_pic);
    imageView.setImageBitmap(takenPictureData);
    uploadImage(takenPictureData, false, retailer_profile_client_transacation_id);


    Log.d("IMAGE_ISSUE", "IMAGE BITMAP : " + takenPictureData);
}
}
} catch (Exception e) {
Log.d("Exception", "" + e.toString());
}
break;

case Constants.SELECT_GALLERY:
if (data != null) {
Uri selectedImageUri = data.getData();
takenPictureData = ImageUtils.getBitmapFromUri(getActivity(), selectedImageUri);

picCallBackImageView1.setImageBitmap(takenPictureData);
uploadImage(takenPictureData, false, retailer_profile_client_transacation_id);


Log.d("IMAGE_ISSUE", "IMAGE BITMAP : " + takenPictureData);
}
break;
}

This is the utility method:

public static Bitmap getBitmapFromUri(Context c, Uri uri)  {

        Bitmap image = null;
        try {
            ParcelFileDescriptor parcelFileDescriptor =
                    c.getContentResolver().openFileDescriptor(uri, "r");
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
            image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
            parcelFileDescriptor.close();
        }
        catch(IOException e){
            if (Constants.PRINT_DEBUG) {
                e.printStackTrace();
                Log.d("URI to Bitmap", "" + e.toString());
            }
        }
        return image;
    }

After getting the Bitmap, I am passing the byte array to my task // convert from bitmap to byte array

  public static byte[] getBytesFromBitmap(Bitmap bitmap) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
        return stream.toByteArray();
    }

And here is my HttpRequestImageUpload.java

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.crashlytics.android.Crashlytics;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class HttpRequestImageUpload extends AsyncTask<byte[], Void, String> {

    Context context;
    private IRequestCallback callback;
    SuperActivity superActivity;
    SuperFragment superFragment;
    HttpPut httpPut;
    int client_transaction_id;
    String str;

    public IRequestCallback getCallback() {
        return callback;
    }

    public void setCallback(IRequestCallback callback) {
        this.callback = callback;
    }

    public HttpRequestImageUpload(SuperActivity superActivity, Context context , int client_transaction_id) {
        this.superActivity = superActivity;
        this.context = context;
        this.client_transaction_id = client_transaction_id;
    }

    public HttpRequestImageUpload(SuperFragment superFragment, Context context , int client_transaction_id) {
        this.superFragment = superFragment;
        this.context = context;
        this.client_transaction_id = client_transaction_id;
    }

    @Override
    protected String doInBackground(byte[]... params) {
        Log.d("IMAGE_ISSUE", "SENT FROM doInBackground() : " + params[0]);
        return upload(params[0]);
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        Log.d("IMAGE_ISSUE", "On postExeceute() : " + s);
        if (s.equalsIgnoreCase("Error")) {
            callback.errorCallBack(s,str);
        } else {
            callback.imageUploadCallBack(s,str);
        }
    }

    @Override
    protected void onCancelled() {
        Log.d("IMAGE_ISSUE", "Cancelled in ImageUpload");
        try {
            if(httpPut != null) {
                httpPut.abort();
            }
        } catch (Exception e) {
            Crashlytics.logException(e);
        }
        super.onCancelled();
    }

    @Override
    protected void onCancelled(String s) {
        super.onCancelled(s);
    }

    public String upload(byte[] byteArrayEntity) {
        setCallback(superActivity != null ? superActivity : superFragment);
        Log.d("IMAGE_ISSUE", "UPLOADING : request " + byteArrayEntity);
        StringBuilder stringBuilder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();


        HttpConnectionParams.setConnectionTimeout(client.getParams(), 120000);
        HttpConnectionParams.setSoTimeout(client.getParams(), 120000);

        httpPut = new HttpPut(CommonUtil.getBaseUrl()+"artefacts?type=Image&client_transaction_id="+client_transaction_id);
        httpPut.addHeader("Authorization", "Bearer " + Prefs.getToken(context));
        httpPut.addHeader("Content-Type", "application/octet-stream");
        httpPut.setEntity(new ByteArrayEntity(byteArrayEntity));

        try {
            HttpResponse response = client.execute(httpPut);
            Log.d("IMAGE_ISSUE", "UPLOADING : Response " + response);
            StatusLine statusLine = response.getStatusLine();
            Log.d("IMAGE_ISSUE", "UPLOADING : Status Line " + statusLine);
            int statusCode = statusLine.getStatusCode();
            Log.d("IMAGE_ISSUE", String.valueOf(statusCode));
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    stringBuilder.append(line);
                }
            } else if (statusCode == 201) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    stringBuilder.append(line);
                }
            } else {
                return ("Error");
            }
        } catch (Exception e) {
            Log.d("IMAGE_ISSUE", "Exception:  " + e.toString());
        }
        return stringBuilder.toString();
    }
}

Well...as I said ...this async task works well for all images captured from camera. But in case of images taken from gallery.... the async task is not executing with 422 status.

This is a very common mistake..I don't know why I did not find any good resources to solve this issue...after looking around it for a few hours...I find that the When i am uploading image from gallery...the size comes out to be much larger than when i capture a bitmap using Camera. The difference is around 50 times larger size for gallery... this is causing an issue with ImageUpload...resulting into 422 Status.

Scaling the image in OnActivityResult() and then sending it to the ImageUploadAsyncTask... worked like charm. Here is the method I used to scale the bitmap.

public static Bitmap scaleImage(Context context, Uri photoUri) throws IOException {
        InputStream is = context.getContentResolver().openInputStream(photoUri);
        BitmapFactory.Options dbo = new BitmapFactory.Options();
        dbo.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, null, dbo);
        is.close();

        int rotatedWidth, rotatedHeight;
        int orientation = getOrientation(context, photoUri);

        if (orientation == 90 || orientation == 270) {
            rotatedWidth = dbo.outHeight;
            rotatedHeight = dbo.outWidth;
        } else {
            rotatedWidth = dbo.outWidth;
            rotatedHeight = dbo.outHeight;
        }

        Bitmap srcBitmap;
        is = context.getContentResolver().openInputStream(photoUri);
        if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
            float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
            float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
            float maxRatio = Math.max(widthRatio, heightRatio);

            // Create the bitmap from file
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = (int) maxRatio;
            srcBitmap = BitmapFactory.decodeStream(is, null, options);
        } else {
            srcBitmap = BitmapFactory.decodeStream(is);
        }
        is.close();

        /*
         * if the orientation is not 0 (or -1, which means we don't know), we
         * have to do a rotation.
         */
        if (orientation > 0) {
            Matrix matrix = new Matrix();
            matrix.postRotate(orientation);

            srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
                    srcBitmap.getHeight(), matrix, true);
        }

        String type = context.getContentResolver().getType(photoUri);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        if (type.equals("image/png")) {
            srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        } else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
            srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        }
        byte[] bMapArray = baos.toByteArray();
        baos.close();
        return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM