douliangbian7323 2019-01-06 22:25
浏览 192
已采纳

使用Android-Image-Cropper将图像发送到服务器使用getCroppedImage()返回NULL

I am using this Github Android Library to crop an image that is selected. That image is then loaded into two CircleImageViews and sent to the server (PHP). It is later accessed by the image URL in the database. The actual image is stored in a folder on the server.

When I was using the default onActivityResult without the library, everything worked great, however, larger images would be flipped. Hence my desire to use this library.

If I try to open the file that's uploaded to the server, this is what I get:

Image Error

First, here is how I start the CropImage Activity:

public void showFileChooser() {
    CropImage.activity()
            .setGuidelines(CropImageView.Guidelines.ON)
            .start(this);
}

Here is my onActivityResult() method and the subsequent method, uploadAvatar() that is called. Note the comment saying my bitmap is returning NULL:

 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
        CropImage.ActivityResult result = CropImage.getActivityResult(data);
        if(resultCode == RESULT_OK) {
            picUri = CropImage.getPickImageResultUri(this, data); //get the image URI
            Log.d(TAG, "CropImage Result URI: "+picUri);

            //THIS RETURNS NULL AND I DON'T KNOW WHY
            bitmap = cropImageView.getCroppedImage(); //Assign the bitmap to the cropImageView

            Picasso.get().load(picUri).into(edit_profile_avatar); //Load it into the CircleImageView
            Picasso.get().load(picUri).into(circle_avatar); //Load it into the DrawerLayout CircleImageView
            uploadAvatar(); //Upload to server (see method)
        } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
            Exception error = result.getError();
            ToastMaker.createLongToast(getApplicationContext(), "Error Cropping Image: "+error);
            Log.d(TAG, "Exception: "+error);
        }
    }
}
public void uploadAvatar() {
    //Progress log to show work being done
    final ProgressDialog progressDialog = new ProgressDialog(EditProfileActivity.this, R.style.Custom_Progress_Dialog);
    progressDialog.setIndeterminate(true);
    progressDialog.setMessage("Doing Stuff...");
    progressDialog.show();
    StringRequest stringRequest = new StringRequest(Request.Method.POST, uploadAvatarUrl, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            try {
                Log.d(TAG, "Volley Response: "+response);
                ToastMaker.createLongToast(getApplicationContext(), "Volley Upload Response: "+response);
                uploadArray = new JSONArray(response);
                JSONObject jsonObject = uploadArray.getJSONObject(0);
                String imageString = jsonObject.getString("image");
                Log.d(TAG, "imageString: "+imageString);
                //Picasso.get().load(imageString).into(edit_profile_avatar);
                //Picasso.get().load(imageString).into(circle_avatar);
                progressDialog.dismiss();
            } catch (Exception e) {
                ToastMaker.createLongToast(getApplicationContext(), "Exception: " + e.getMessage());
                progressDialog.dismiss();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            ToastMaker.createLongToast(getApplicationContext(), "Volley Error: " + error);
            Log.d(TAG, "VolleyError: " + error);
            progressDialog.dismiss();
        }
    }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();
            //String imageData = imageToString(bitmap);
            //params.put("image", imageData);
            params.put("image", picUri.toString());
            params.put("username", logged_in_username);
            return params;
        }
    };
    RequestQueue requestQueue = Volley.newRequestQueue(EditProfileActivity.this);
    requestQueue.add(stringRequest);
}

If you notice, I left the commented out line in my getParams() method so you could see the original method I used. Here it is:

private String imageToString(Bitmap bitmap) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
    byte[] imageBytes = outputStream.toByteArray();

    return Base64.encodeToString(imageBytes, Base64.DEFAULT);
}

If I tried to use that method on the new CropImageView bitmap, I got a NullPointerException.

Here is the short PHP script that handles it. Keep in mind, it worked before using this CropImage Library.

<?php

include '../../../config/DB.php';

try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }


if($_SERVER['REQUEST_METHOD'] === 'POST') {

    //Get the username for query
    $username = $_POST['username'];
    //Get the image
    $image = $_POST['image'];
    //Define upload path
    $target_dir = '../../users/'.$username.'/uploads';

    //Delete all other files
    $files = glob('../../users/'.$username.'/uploads/*');
    foreach($files as $file) {
        if(is_file($file)) {
            unlink($file);
        }
    }

    //Create random number + timestamp for new name
    $imageID = rand().'_'.time();
    $target_dir = $target_dir .'/'.$imageID.'.jpg';
    $db_dir = '../users/'.$username.'/uploads/'.$imageID.'.jpg';

    //To see what data is returned
    $user_info = array();

    //If upload is successful, put the path in the database
    if(file_put_contents($target_dir, base64_decode($image))) {
        $user_info[] = array('image'=>$db_dir);
        $insert = $db->updateRow('UPDATE users SET avatar=? WHERE username=?', [$db_dir, $username]);
        echo json_encode($user_info);
    } else {
        echo json_encode('Error');
    }
}

Here is what is written to the database:

id | username | avatar
 1 | username | ../users/username/uploads/2132273469_1546812127.jpg

And finally, here is what comes back in my logs:

CropImage Result URI: file:///storage/emulated/0/Android/data/com.companyname.appname/cache/pickImageResult.jpeg
Volley Response: [{"image":"..\/users\/username\/uploads\/2132273469_1546812127.jpg"}]

Has anyone ever used this library? What am I missing here? The documentation shows nothing about uploading to a server, only setting an ImageView to the bitmap (which works).

  • 写回答

1条回答 默认 最新

  • douni9620 2019-01-06 23:40
    关注

    Alright. I needed to grab the URI from the onActivityResult and assign it to the Bitmap. That's why it was returning null.

    Here is my new onActivityResult:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
            Log.d(TAG, "REQUEST CODE: "+requestCode);
            CropImage.ActivityResult result = CropImage.getActivityResult(data);
            if(resultCode == RESULT_OK) {
                try {
    
                    //THIS FIXED IT. NO MORE NULL!
                    picUri = result.getUri();
                    bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), picUri);
                } catch(Exception e) {
                    ToastMaker.createLongToast(getApplicationContext(), "Exception: "+e.getMessage());
                }
                edit_profile_avatar.setImageBitmap(bitmap);
                circle_avatar.setImageBitmap(bitmap);
                uploadAvatar(); 
            } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
                Exception error = result.getError();
                ToastMaker.createLongToast(getApplicationContext(), "Error Cropping Image: "+error);
                Log.d(TAG, "Exception: "+error);
            }
        }
    }
    

    The image successfully loads in the CircleImageView, gets sent to the server, and correctly shows up in the respective user's directory.

    It also shows up just fine in the database:

     mysql> select id, username, avatar from users;
    +----+------------------+-------------------------------------------------------+
    | id | username         | avatar                                                |
    +----+------------------+-------------------------------------------------------+
    |  1 | username         | ../users/username/uploads/1041075557_1546817783.jpeg  |
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?