[英]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.