从图库中选择一张图片 Android
choose an image from gallery Android
我正在编写一个代码,使用户能够从图库中选择个人资料图片。至此代码如下
(1) 在activity下的字段中,我声明了一个按钮,一个图像视图和一个静态整数。
private Button btnChooseProfile;
private ImageView ivProfile;
private static final int RESULT_LOAD_IMAGE = 1;
(2) 现在,我通过 onCreate 方法让它们真正出现在屏幕上。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate();
setContentView(R.layout.activity_register);
btnChooseProfile = (Button) findViewById(R.id.btnChooseProfile);
ivProfile = (ImageView) findViewById(R.id.ivProfile);
btnChooseProfile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RESULT_LOAD_IMAGE);
}
};
(3) 最后,我覆盖了 onActivityResult 方法来定义单击 btnChooseProfile 按钮后发生的情况。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String imagePath = cursor.getString(columnIndex);
cursor.close();
ivProfile.setImageBitmap(BitmapFactory.decodeFile(imagePath));
}
}
当我 运行 代码时,我设法访问了画廊。选择图像后,我希望 imageview 包含选定的图片,但应用程序会以某种方式结束。
我已经阅读了该站点中建议的很多解决方案,并且代码片段本身似乎没有问题。如果我遗漏了什么,请给我一些建议,我们将不胜感激。
谢谢。
编辑这里是 logcat。 (日志级别:调试)
07-13 15:15:25.961 28110-28110/com.marshall.gruppo E/﹕ Device driver API match
Device driver API version: 29
User space API version: 29
07-13 15:15:25.961 28110-28110/com.marshall.gruppo E/﹕ mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Tue Jul 22 19:59:34 KST 2014
07-13 15:15:26.051 28110-28110/com.marshall.gruppo D/OpenGLRenderer﹕ Enabling debug mode 0
07-13 15:15:28.726 28110-28110/com.marshall.gruppo D/dalvikvm﹕ GC_FOR_ALLOC freed 153K, 6% free 14269K/15064K, paused 9ms, total 9ms
07-13 15:15:28.751 28110-28110/com.marshall.gruppo D/AbsListView﹕ Get MotionRecognitionManager
07-13 15:15:28.831 28110-28110/com.marshall.gruppo D/dalvikvm﹕ GC_FOR_ALLOC freed 115K, 6% free 14329K/15088K, paused 12ms, total 12ms
07-13 15:15:28.861 28110-28110/com.marshall.gruppo I/dalvikvm-heap﹕ Grow heap (frag case) to 33.649MB for 19955728-byte allocation
07-13 15:15:28.876 28110-28119/com.marshall.gruppo D/dalvikvm﹕ GC_FOR_ALLOC freed 1K, 3% free 33816K/34580K, paused 13ms, total 13ms
07-13 15:15:33.401 28110-28110/com.marshall.gruppo W/IInputConnectionWrapper﹕ showStatusIcon on inactive InputConnection
07-13 15:15:37.681 28110-28110/com.marshall.gruppo D/AbsListView﹕ onDetachedFromWindow
我不会做你在 onActivityResult 中做的所有事情...它是主线程,因此不推荐访问 DB (ContentProvider) 和解码 Bitmap。启动 AsyncTask 或其他东西。
有时返回的数据为空(是的,它发生了)- 确保您的代码为空。添加一些日志。
我相信你应该不错
这可能是图片尺寸问题。试试这个代码来缩小你的图片。
Bitmap photo;
File file = new File(picturePath);
int file_size = Integer
.parseInt(String.valueOf(file.length() / 1024));
if (file_size > 2048)
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
photo = BitmapFactory.decodeFile(picturePath, options);
} else if (file_size > 1024)
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
photo = BitmapFactory.decodeFile(picturePath, options);
} else
photo = BitmapFactory.decodeFile(picturePath);
ivProfile.setImageBitmap(photo);
public Bitmap compressImage(String imageUri) {
String filePath = imageUri;
// String filePath = getRealPathFromURI(imageUri);
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
// by setting this field as true, the actual bitmap pixels are not
// loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
// max Height and width values of the compressed image is taken as
// 816x612
/*
* float maxHeight = 816.0f; float maxWidth = 612.0f;
*/
float maxHeight = 1080.0f;
float maxWidth = 800.0f;
float imgRatio = actualWidth / (float) actualHeight;
float maxRatio = maxWidth / (float) maxHeight;
// width and height values are set maintaining the aspect ratio of the
// image
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
// setting inSampleSize value allows to load a scaled down version of
// the original image
options.inSampleSize = calculateInSampleSize(options, actualWidth,
actualHeight);
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false;
// this options allow android to claim the bitmap memory if it runs low
// on memory
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
// load the bitmap from its path
bmp = BitmapFactory.decodeFile(filePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight,
Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2,
middleY - bmp.getHeight() / 2, new Paint(
Paint.FILTER_BITMAP_FLAG));
// check the rotation of the image and display it properly
ExifInterface exif;
try {
exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 0);
Log.d("EXIF", "Exif: " + orientation);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 3) {
matrix.postRotate(180);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 8) {
matrix.postRotate(270);
Log.d("EXIF", "Exif: " + orientation);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
true);
} catch (IOException e) {
e.printStackTrace();
}
return scaledBitmap;
}
我正在编写一个代码,使用户能够从图库中选择个人资料图片。至此代码如下
(1) 在activity下的字段中,我声明了一个按钮,一个图像视图和一个静态整数。
private Button btnChooseProfile;
private ImageView ivProfile;
private static final int RESULT_LOAD_IMAGE = 1;
(2) 现在,我通过 onCreate 方法让它们真正出现在屏幕上。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate();
setContentView(R.layout.activity_register);
btnChooseProfile = (Button) findViewById(R.id.btnChooseProfile);
ivProfile = (ImageView) findViewById(R.id.ivProfile);
btnChooseProfile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RESULT_LOAD_IMAGE);
}
};
(3) 最后,我覆盖了 onActivityResult 方法来定义单击 btnChooseProfile 按钮后发生的情况。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String imagePath = cursor.getString(columnIndex);
cursor.close();
ivProfile.setImageBitmap(BitmapFactory.decodeFile(imagePath));
}
}
当我 运行 代码时,我设法访问了画廊。选择图像后,我希望 imageview 包含选定的图片,但应用程序会以某种方式结束。
我已经阅读了该站点中建议的很多解决方案,并且代码片段本身似乎没有问题。如果我遗漏了什么,请给我一些建议,我们将不胜感激。
谢谢。
编辑这里是 logcat。 (日志级别:调试)
07-13 15:15:25.961 28110-28110/com.marshall.gruppo E/﹕ Device driver API match
Device driver API version: 29
User space API version: 29
07-13 15:15:25.961 28110-28110/com.marshall.gruppo E/﹕ mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Tue Jul 22 19:59:34 KST 2014
07-13 15:15:26.051 28110-28110/com.marshall.gruppo D/OpenGLRenderer﹕ Enabling debug mode 0
07-13 15:15:28.726 28110-28110/com.marshall.gruppo D/dalvikvm﹕ GC_FOR_ALLOC freed 153K, 6% free 14269K/15064K, paused 9ms, total 9ms
07-13 15:15:28.751 28110-28110/com.marshall.gruppo D/AbsListView﹕ Get MotionRecognitionManager
07-13 15:15:28.831 28110-28110/com.marshall.gruppo D/dalvikvm﹕ GC_FOR_ALLOC freed 115K, 6% free 14329K/15088K, paused 12ms, total 12ms
07-13 15:15:28.861 28110-28110/com.marshall.gruppo I/dalvikvm-heap﹕ Grow heap (frag case) to 33.649MB for 19955728-byte allocation
07-13 15:15:28.876 28110-28119/com.marshall.gruppo D/dalvikvm﹕ GC_FOR_ALLOC freed 1K, 3% free 33816K/34580K, paused 13ms, total 13ms
07-13 15:15:33.401 28110-28110/com.marshall.gruppo W/IInputConnectionWrapper﹕ showStatusIcon on inactive InputConnection
07-13 15:15:37.681 28110-28110/com.marshall.gruppo D/AbsListView﹕ onDetachedFromWindow
我不会做你在 onActivityResult 中做的所有事情...它是主线程,因此不推荐访问 DB (ContentProvider) 和解码 Bitmap。启动 AsyncTask 或其他东西。
有时返回的数据为空(是的,它发生了)- 确保您的代码为空。添加一些日志。
我相信你应该不错
这可能是图片尺寸问题。试试这个代码来缩小你的图片。
Bitmap photo;
File file = new File(picturePath);
int file_size = Integer
.parseInt(String.valueOf(file.length() / 1024));
if (file_size > 2048)
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
photo = BitmapFactory.decodeFile(picturePath, options);
} else if (file_size > 1024)
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
photo = BitmapFactory.decodeFile(picturePath, options);
} else
photo = BitmapFactory.decodeFile(picturePath);
ivProfile.setImageBitmap(photo);
public Bitmap compressImage(String imageUri) {
String filePath = imageUri;
// String filePath = getRealPathFromURI(imageUri);
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
// by setting this field as true, the actual bitmap pixels are not
// loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
// max Height and width values of the compressed image is taken as
// 816x612
/*
* float maxHeight = 816.0f; float maxWidth = 612.0f;
*/
float maxHeight = 1080.0f;
float maxWidth = 800.0f;
float imgRatio = actualWidth / (float) actualHeight;
float maxRatio = maxWidth / (float) maxHeight;
// width and height values are set maintaining the aspect ratio of the
// image
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
// setting inSampleSize value allows to load a scaled down version of
// the original image
options.inSampleSize = calculateInSampleSize(options, actualWidth,
actualHeight);
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false;
// this options allow android to claim the bitmap memory if it runs low
// on memory
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
// load the bitmap from its path
bmp = BitmapFactory.decodeFile(filePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight,
Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2,
middleY - bmp.getHeight() / 2, new Paint(
Paint.FILTER_BITMAP_FLAG));
// check the rotation of the image and display it properly
ExifInterface exif;
try {
exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 0);
Log.d("EXIF", "Exif: " + orientation);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 3) {
matrix.postRotate(180);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 8) {
matrix.postRotate(270);
Log.d("EXIF", "Exif: " + orientation);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
true);
} catch (IOException e) {
e.printStackTrace();
}
return scaledBitmap;
}