简体   繁体   English

在上传之前,请调整从图库或照相机拍摄的图像的大小

[英]Resize image taken from gallery or camera, before being uploaded

I have a form in my site that allows the user to upload a photo. 我的网站上有一个表格,允许用户上传照片。 My android app uses WebView to allow users access the site. 我的Android应用程序使用WebView允许用户访问该网站。 On click of the upload button the app allows the user to choose between an image already existing in the gallery or take a new photo and upload that image. 单击上传按钮后,该应用程序允许用户在图库中已经存在的图像之间进行选择,或者拍摄新照片并上传该图像。 The code I have used for this is 我使用的代码是

showAttachmentDialog is called by the openFileChooser showAttachmentDialog由openFileChooser调用

private void showAttachmentDialog(ValueCallback<Uri> uploadMsg) {
        this.mUploadMessage = uploadMsg;

        File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyApp");
        // Create the storage directory if it does not exist
        if (! imageStorageDir.exists()){
            imageStorageDir.mkdirs();                  
        }
        File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");


        this.imageUri= Uri.fromFile(file);


        final List<Intent> cameraIntents = new ArrayList<Intent>();
        final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        final PackageManager packageManager = getPackageManager();
        final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
        for(ResolveInfo res : listCam) {
            final String packageName = res.activityInfo.packageName;
            final Intent intent = new Intent(captureIntent);
            intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
            intent.setPackage(packageName);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            cameraIntents.add(intent);
        }


       // mUploadMessage = uploadMsg; 
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);  
        intent.addCategory(Intent.CATEGORY_OPENABLE);  
        intent.setType("image/*"); 
        Intent chooserIntent = Intent.createChooser(intent,"Image Chooser");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
        this.startActivityForResult(chooserIntent,  FILECHOOSER_RESULTCODE);
    }

My onActivityResult 我的onActivityResult

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == FILECHOOSER_RESULTCODE) {

            if (null == this.mUploadMessage) {
                return;
            }

            Uri result;
            if (resultCode != RESULT_OK) {
                result = null;
            } else {
                result = intent == null ? this.imageUri : intent.getData(); // retrieve from the private variable if the intent is null
            }

            this.mUploadMessage.onReceiveValue(result);
            this.mUploadMessage = null;



        }
    }

I would like to be able to change the size of the image before I upload it and I want this to be done on the phone , not in the webpage. 我希望能够在上传图片之前更改图片的大小,并且希望通过电话(而不是网页)完成此操作。 I also want to delete the resized image from the phone when this is done and keep the prototype. 完成此操作后,我还想从手机中删除调整大小的图像,并保留原型。 Could you suggest me a way to do this? 你能建议我这样做吗? I show several cases in SO where it is suggested to create a bitmap and resize it in the desired size with createScaledBitmap but I am not sure which is the best way to do this in my case. 我在SO中展示了几种情况,建议创建一个位图并使用createScaledBitmap将其调整为所需的大小,但是我不确定哪种方法是我所用的最佳方法。 Where should this take place? 这应该在哪里发生? In my onActivityResult? 在我的onActivityResult中? Thanks in advance! 提前致谢!

--------------------EDIT---------------------- - - - - - - - - - - 编辑 - - - - - - - - - - -

private File imageStorageDir,file; 私有文件imageStorageDir,file;

I declared these in my main Activity and added the following snippet in my onActivityResult 我在主Activity中声明了这些代码,并在onActivityResult中添加了以下代码段

String newPath=file.getAbsolutePath();
            Bitmap bMap= BitmapFactory.decodeFile(newPath);
            Bitmap out = Bitmap.createScaledBitmap(bMap, 150, 150, false);
            File resizedFile = new File(imageStorageDir, "resized.png");

            OutputStream fOut=null;
            try {
                fOut = new BufferedOutputStream(new FileOutputStream(resizedFile));
                out.compress(Bitmap.CompressFormat.PNG, 100, fOut);
                fOut.flush();
                fOut.close();
                bMap.recycle();
                out.recycle();

            } catch (Exception e) { // TODO

            }

Now the image is being resized and uploaded when taking a photo with the camera but when I am using the gallery I get a NullPointerException 现在,使用相机拍摄照片时,正在调整图像大小并上传,但是当我使用图库时,我得到了NullPointerException

05-23 10:12:50.354: E/BitmapFactory(1376): Unable to decode stream: java.io.FileNotFoundException: /storage/sdcard/Pictures/MyApp/IMG_1400854361171.jpg: open failed: ENOENT (No such file or directory)
05-23 10:12:50.364: D/AndroidRuntime(1376): Shutting down VM
05-23 10:12:50.414: W/dalvikvm(1376): threadid=1: thread exiting with uncaught exception (group=0x41465700)
05-23 10:12:50.494: E/AndroidRuntime(1376): FATAL EXCEPTION: main
05-23 10:12:50.494: E/AndroidRuntime(1376): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://media/external/images/media/76 }} to activity {com.example.sinatra19/com.example.sinatra19.Sinatra22Activity}: java.lang.NullPointerException
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3367)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3410)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.app.ActivityThread.access$1100(ActivityThread.java:141)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1304)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.os.Looper.loop(Looper.java:137)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.app.ActivityThread.main(ActivityThread.java:5103)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at java.lang.reflect.Method.invokeNative(Native Method)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at java.lang.reflect.Method.invoke(Method.java:525)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at dalvik.system.NativeStart.main(Native Method)
05-23 10:12:50.494: E/AndroidRuntime(1376): Caused by: java.lang.NullPointerException
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:482)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at com.example.sinatra19.Sinatra22Activity.onActivityResult(Sinatra22Activity.java:158)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.app.Activity.dispatchActivityResult(Activity.java:5322)
05-23 10:12:50.494: E/AndroidRuntime(1376):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3363)
05-23 10:12:50.494: E/AndroidRuntime(1376):     ... 11 more

-----------------------EDIT2------------------------ ----------------------- EDIT2 ------------------------

This snipet 这个片段

           String newPath=getRealPathFromURI(getApplicationContext(), result);


            Bitmap bMap= BitmapFactory.decodeFile(newPath);
            Bitmap out = Bitmap.createScaledBitmap(bMap, 150, 150, false);
            File resizedFile = new File(imageStorageDir, "resize.png");

            OutputStream fOut=null;
            try {
                fOut = new BufferedOutputStream(new FileOutputStream(resizedFile));
                out.compress(Bitmap.CompressFormat.PNG, 100, fOut);
                fOut.flush();
                fOut.close();
                bMap.recycle();
                out.recycle();

            } catch (Exception e) { // TODO

            }
this.mUploadMessage.onReceiveValue(Uri.fromFile(resizedFile));
        this.mUploadMessage = null;

calling 调用

public String getRealPathFromURI(Context context, Uri contentUri) {
          Cursor cursor = null;
          try { 
            String[] proj = { MediaStore.Images.Media.DATA };
            cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
          } finally {
            if (cursor != null) {
              cursor.close();
            }
          }
        }

works when the user chooses photo from gallery and crashes when taking photo from camera. 用户从图库中选择照片时有效,而从相机拍摄照片时崩溃。 I need the way to combine them 我需要结合它们的方法

Well all it needed was an if statement to check what method the user chose. 好吧,它所需要的只是一个if语句,以检查用户选择哪种方法。 file is created in the showAttachmentDialog and so the private imageUri allways has the Uri of that file. 文件是在showAttachmentDialog中创建的,因此私有imageUri始终具有该文件的Uri。 When the user chooses the camera option result also has that values whereas when he chooses gallery result has the Uri of the image chosen from the galery 当用户选择相机选项时,结果也具有该值,而当用户选择图库结果时,其结果是从图库中选择的图像的Uri

if(result==this.imageUri){
            newPath=file.getAbsolutePath();}
            else{
            newPath=getRealPathFromURI(getApplicationContext(), result);}

The final code is 最终的代码是

@Override
    //Receives the results of startActivityFromResult
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        String newPath;
        if (requestCode == FILECHOOSER_RESULTCODE) {

            if (null == this.mUploadMessage) {
                return;
            }

            Uri result;
            if (resultCode != RESULT_OK) {
                result = null;
            } else {
                result = intent == null ? this.imageUri : intent.getData(); // retrieve from the private variable if the intent is null
                Log.e("result",result.toString() );
                Log.e("intent",this.imageUri.toString() );

            }

            if(result==this.imageUri){
            newPath=file.getAbsolutePath();}
            else{
            newPath=getRealPathFromURI(getApplicationContext(), result);}

            Bitmap bMap= BitmapFactory.decodeFile(newPath);
            Bitmap out = Bitmap.createScaledBitmap(bMap, 150, 150, false);
            File resizedFile = new File(imageStorageDir, "resize.png");

            OutputStream fOut=null;
            try {
                fOut = new BufferedOutputStream(new FileOutputStream(resizedFile));
                out.compress(Bitmap.CompressFormat.PNG, 100, fOut);
                fOut.flush();
                fOut.close();
                bMap.recycle();
                out.recycle();

            } catch (Exception e) { // TODO

            }


            this.mUploadMessage.onReceiveValue(Uri.fromFile(resizedFile));
            this.mUploadMessage = null;
            //resizedFile.delete();


        }
    }

    public String getRealPathFromURI(Context context, Uri contentUri) {
          Cursor cursor = null;
          try { 
            String[] proj = { MediaStore.Images.Media.DATA };
            cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
          } finally {
            if (cursor != null) {
              cursor.close();
            }
          }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在保存之前调整从相机拍摄的图像的大小 - Resize Image taken from Camera before being Saved 从相机拍摄后将图像保存到图库 - save image to the gallery after taken from the camera 如何在图库中的imageView上设置图像以及在Android中由相机拍摄的图像? - How to set an image on imageView from the gallery and image taken by camera in Android? Android通过使用文件系统保存从相机或图库拍摄的图像 - Android save taken image from camera or gallery by using file system 如何检查图库中的图像是从相机还是屏幕截图中拍摄的? - How to check if image in gallery was taken from camera or screenshot? 如何旋转从相机或画廊拍摄的图像? - How rotate image taken from camera or gallery.? ImageView不显示从手机摄像头或照片库拍摄的图像 - ImageView does not display image taken from phone camera or photo gallery 是否可以检查图像是由相机拍摄的还是由JavaScript从照片库上传的? - Is it possible to check if an image is taken by camera or uploaded from photo library by JavaScript? 从图库或相机中选择后调整图像大小的API - API to resize an image after selected from gallery or camera 无法从图库中获取相机拍摄的图像 - Cannot fetch images taken by camera from Gallery
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM