Android 在上传之前,调整从多媒体资料或相机拍摄的图像的大小

Android 在上传之前,调整从多媒体资料或相机拍摄的图像的大小,android,file-upload,image-resizing,Android,File Upload,Image Resizing,我的网站上有一个表单,允许用户上传照片。我的android应用程序使用WebView允许用户访问该网站。点击上传按钮,应用程序允许用户在画廊中已有的图片或拍摄新照片并上传该图片之间进行选择。我使用的代码是 openFileChooser调用showAttachmentDialog private void showAttachmentDialog(ValueCallback<Uri> uploadMsg) { this.mUploadMessage = uploadM

我的网站上有一个表单,允许用户上传照片。我的android应用程序使用WebView允许用户访问该网站。点击上传按钮,应用程序允许用户在画廊中已有的图片或拍摄新照片并上传该图片之间进行选择。我使用的代码是

openFileChooser调用showAttachmentDialog

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);
    }
我想能够改变大小的图像之前,我上传它,我希望这是在电话上完成,而不是在网页上。我还想删除手机的大小图像时,这是做,并保留原型。你能给我一个建议吗?我展示了几种情况,建议使用createScaledBitmap创建位图并将其调整为所需大小,但我不确定在我的情况下,哪种方法是最好的。这应该在哪里发生?在我的onActivityResult中? 提前谢谢

--------------------编辑----------------------

私有文件imageStorageDir,文件

我在主要活动中声明了这些,并在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;



        }
    }
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

            }
现在,当我使用相机拍照时,图像正在调整大小并上传,但是当我使用gallery时,我得到了一个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
-----------------------编辑2------------------------

这只鹬

           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;
召唤

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();
            }
          }
        }

当用户从“多媒体资料”中选择照片时工作,从相机拍照时崩溃。我需要将它们结合起来的方法,只需要一个if语句来检查用户选择的方法。文件是在showAttachmentDialog中创建的,因此私有imageUri始终具有该文件的Uri。当用户选择相机选项时,结果也具有该值,而当用户选择gallery时,结果具有从galery中选择的图像的Uri

if(result==this.imageUri){
            newPath=file.getAbsolutePath();}
            else{
            newPath=getRealPathFromURI(getApplicationContext(), result);}
最后的代码是

@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();
            }
          }
        }

如果我使用相机,bMap总是空的。有什么帮助吗?此codeHi标记中也未定义文件。我已经很久没有玩过安卓了。这段代码在之前的KitKat avds中有效,但在以后的android版本中可能会出现问题。如果问题仍然存在,我建议您提出一个新问题,并提供代码