take photo and upload it to server without any com

2019-08-20 05:06发布

I'm trying to take a picture from device camera or pick it up from the gallery and upload it to the server via the volley everything works fine but the image quality is so bad

private void dispatchTakePictureIntent()
{
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent , CAMERA_REQUEST_CODE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data { 
    switch (requestCode) {
    case CAMERA_REQUEST_CODE:
    if ( resultCode == RESULT_OK){                 
    Bundle bundle = data.getExtras();
    bitmap = (Bitmap) bundle.get("data");
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);                    
}
break;

and getParams method :

    byte[] a = convertBitmapToByteArrayUncompressed(bitmap);
    params.put("img" , Base64.encodeToString(a , Base64.DEFAULT));

public static byte[] convertBitmapToByteArrayUncompressed(Bitmap bitmap){
    ByteBuffer byteBuffer = ByteBuffer.allocate(bitmap.getByteCount());
    bitmap.copyPixelsToBuffer(byteBuffer);
    byteBuffer.rewind();
    return byteBuffer.array();
}

3条回答
成全新的幸福
2楼-- · 2019-08-20 05:48

use getParcelableExtra(), instead of getExtras() for small size images.

Bitmap bitmap = (Bitmap) intent.getParcelableExtra("data");

If your images are too large, you have to compress them and send to the other activity. Then you can get compressed bitmap and uncompress it in second activity. Try below code.

1st Activity

Intent intent = new Intent(this, SecondActivity.class);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPG, 100, stream);
byte[] bytes = stream.toByteArray(); 
intent.putExtra("bitmap",bytes);

2nd Activity

byte[] bytes = getIntent().getByteArrayExtra("bitmap");
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
查看更多
Summer. ? 凉城
3楼-- · 2019-08-20 05:54

From Naugat Taking picture would be different.

Create a image file fist:

String mCurrentPhotoPath;

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
        imageFileName,  /* prefix */
        ".jpg",         /* suffix */
        storageDir      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = image.getAbsolutePath();
    return image;
}

Then dispatch take picture intent

static final int REQUEST_TAKE_PHOTO = 1;

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
            ...
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this,
                                                  "com.example.android.fileprovider",
                                                  photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }
}

In your onActivity result check for RESULT_OK for a successful capture.

if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK)

You already got the image path. Now use mCurrentPhotoPath to upload process.

Also, you need to implement file provider.

In your Manifest add this:

<application>
   ...
   <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.android.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"></meta-data>
    </provider>
    ...
</application>

In XML in resource dir and add this:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>

Now you will get a full-size image from a camera.

Source: https://developer.android.com/training/camera/photobasics.html

查看更多
We Are One
4楼-- · 2019-08-20 06:07

You should have to use multipart entity to send image without compression. using multipart entity your image quality also will be maintained. Please follow this to send image using volley

public class MultipartReq extends JsonObjectRequest {

    private static final String FILE_PART_NAME = "file";
    private static final String STRING_PART_NAME = "text";

    private final File mFilePart;
    //private final String mStringPart;


    MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
    HttpEntity httpEntity;
    Context context;

    private Map<String, String> params;
    public MultipartReq(Context context, int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener, File file, Map<String, String> params) {
        super(method, url, jsonRequest, listener, errorListener);

        this.context = context;
        mFilePart = file;
        entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);    
        this.params = params;
        buildMultipartEntity();
        httpEntity = entityBuilder.build();

    }


    private void buildMultipartEntity() {

        try {
            if (mFilePart.exists()) {                                           entityBuilder.addBinaryBody(FILE_PART_NAME, mFilePart, ContentType.create(mimeType), mFilePart.getName());

                }
                try {
                    if(!params.isEmpty()){
                        for (String key: params.keySet()){
                             entityBuilder.addPart(key, new StringBody(params.get(key),ContentType.TEXT_PLAIN));

                        }
                    }
                } catch (Exception e) {
                    VolleyLog.e("UnsupportedEncodingException");
                }


            } else {
                ShowLog.e("no such file");
            }
        } catch (Exception e) {
            ShowLog.e("UnsupportedEncodingException");
        }
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        HashMap<String, String> params = new HashMap<String, String>();

        return params;
    }


    @Override
    public String getBodyContentType() {
        return httpEntity.getContentType().getValue();
    }

    @Override
    public byte[] getBody() {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            httpEntity.writeTo(bos);
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }


    @Override
    protected void deliverResponse(JSONObject response) {
        super.deliverResponse(response);
    }
}
查看更多
登录 后发表回答