简单的概念,但我失败了。我的应用程序要求提供图像,我想为用户提供使用图库、文件浏览器或相机获取图像的选项。然后图像被旋转、缩放并上传到服务器。
首先,我创建意图。
protected void openImageIntent() {
// Determine Uri of camera image to save.
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "tpics" + File.separator);
root.mkdirs();
final String fname = "img_"+ System.currentTimeMillis() + ".jpg";
final File sdImageMainDirectory = new File(root, fname);
outputFileUri = Uri.fromFile(sdImageMainDirectory);
// Camera.
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, outputFileUri);
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, Constants.PICK_EXISTING_PHOTO_RESULT_CODE);
}
然后,在选择图像后,我有我的 onActivityResult 代码。
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case Constants.PICK_EXISTING_PHOTO_RESULT_CODE: {
if (resultCode == Activity.RESULT_OK) {
Uri selectedImageUri = (data == null ? true : MediaStore.ACTION_IMAGE_CAPTURE.equals(data.getAction())) ? outputFileUri : (data == null ? null : data.getData());
Log.d("URI", selectedImageUri.toString());
trophyImage = new TrophyImage(mCtx, selectedImageUri);
try {
imageBytes = trophyImage.scaleImage();
image.setImageBitmap(BitmapFactory.decodeByteArray(
imageBytes, 0, imageBytes.length));
image.invalidate();
} catch (IOException e) {
Utility.handleExternalError(
mCtx,
getString(R.string.error_error),
getString(R.string.error_unable_to_scale_image_is_is_corrupt));
}
} else {
Utility.showToast(mCtx, "No image selected.");
}
break;
}
这是我的 TrophyImage 课程。
public class TrophyImage {
private Context mCtx;
private Uri mImageUri;
private static int MAX_IMAGE_DIMENSION = 720;
private String type;
private JSONServerClient mClient;
public TrophyImage(Context mCtx, Uri imageUri) {
this.mCtx = mCtx;
this.mImageUri = imageUri;
this.mClient = new JSONServerClient((Activity) mCtx);
}
/**
* Scales and orients images taken from the gallery.
*
* @param context
* @param photoUri
* @return
* @throws IOException
*/
public byte[] scaleImage() throws IOException {
InputStream is = mCtx.getContentResolver().openInputStream(mImageUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();
int rotatedWidth, rotatedHeight;
int orientation = getOrientation();
if (orientation == 90 || orientation == 270) {
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = mCtx.getContentResolver().openInputStream(mImageUri);
if (rotatedWidth > MAX_IMAGE_DIMENSION
|| rotatedHeight > MAX_IMAGE_DIMENSION) {
float widthRatio = ((float) rotatedWidth)
/ ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight)
/ ((float) MAX_IMAGE_DIMENSION);
float maxRatio = Math.max(widthRatio, heightRatio);
// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
srcBitmap = BitmapFactory.decodeStream(is);
}
is.close();
/*
* if the orientation is not 0 (or -1, which means we don't know), we
* have to do a rotation.
*/
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0,
srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (type.equals("image/png")) {
srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
} else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
byte[] bMapArray = baos.toByteArray();
baos.close();
return bMapArray;
}
public int getOrientation() {
/* it's on the external media. */
Log.d("mImageUri", mImageUri.toString());
Cursor cursor = mCtx.getContentResolver().query(mImageUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION },
null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
public String uploadPhoto(final byte[] imageBytes, final String fileName) throws IOException {
String fileID = null;
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
try {
JSONObject dataOut = new JSONObject();
dataOut.put("file", encodedImage);
dataOut.put("filename", fileName);
mClient.call(dataOut, JSONServerClient.FILE_UPLOAD);
// get the result so we know the file id (fid)
// and we can assign it to the correct field.
String js = mClient.getResponse();
JSONObject jo = new JSONObject(js);
fileID = jo.getString("fid");
} catch (JSONException e) {
e.printStackTrace();
}
return fileID;
};
public String getFileName() {
return Utility.getFileNameByUri(mImageUri, mCtx);
}
public Uri getmImageUri() {
return mImageUri;
}
}
我在 TrophyImage.getOrientation() 的以下行(第 118 行)收到 nullPointerException
if (cursor.getCount() != 1)
我测试游标的值,当然,它是空的。我不知道为什么它是空的。看来它应该返回我需要的数据。
以防万一需要。这是整个错误堆栈。
07-28 14:15:51.573: E/AndroidRuntime(29734): FATAL EXCEPTION: main
07-28 14:15:51.573: E/AndroidRuntime(29734): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { dat=file:///storage/sdcard0/tpics/img_1375038937506.jpg }} to activity {com.seine.trophy.main/com.seine.trophy.main.TrophyCreate}: java.lang.NullPointerException
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.deliverResults(ActivityThread.java:3322)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3365)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.access$1200(ActivityThread.java:141)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1315)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.os.Handler.dispatchMessage(Handler.java:99)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.os.Looper.loop(Looper.java:137)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.main(ActivityThread.java:5059)
07-28 14:15:51.573: E/AndroidRuntime(29734): at java.lang.reflect.Method.invokeNative(Native Method)
07-28 14:15:51.573: E/AndroidRuntime(29734): at java.lang.reflect.Method.invoke(Method.java:511)
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
07-28 14:15:51.573: E/AndroidRuntime(29734): at dalvik.system.NativeStart.main(Native Method)
07-28 14:15:51.573: E/AndroidRuntime(29734): Caused by: java.lang.NullPointerException
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.seine.trophy.main.TrophyImage.getOrientation(TrophyImage.java:118)
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.seine.trophy.main.TrophyImage.scaleImage(TrophyImage.java:58)
07-28 14:15:51.573: E/AndroidRuntime(29734): at com.seine.trophy.main.TrophyCreate.onActivityResult(TrophyCreate.java:333)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.Activity.dispatchActivityResult(Activity.java:5242)
07-28 14:15:51.573: E/AndroidRuntime(29734): at android.app.ActivityThread.deliverResults(ActivityThread.java:3318)
07-28 14:15:51.573: E/AndroidRuntime(29734): ... 11 more
非常感谢任何帮助。