如何压缩位图图像?
how to compress the bitmap image?
我想上传图片到服务器。将我的图像转换为位图,但仍然出现错误。位图太大,无法上传到纹理
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == this.RESULT_CANCELED) {
return;
}
if (requestCode == GALLERY) {
if (data != null) {
contentURI = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(contentURI, filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if (l == 0) {
imagePath = cursor.getString(columnIndex);
}
}
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
String path = saveImage(bitmap);
Toast.makeText(SignUpActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();
BitmapDrawable bdrawable = new BitmapDrawable(this.getResources(), bitmap);
if (l == 0) {
captureAadhar.setBackground(bdrawable);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
else if (requestCode == CAMERA) {
//if (checkPermissionREAD_EXTERNAL_STORAGE(this)) {
// do your stuff..
if (data != null) {
contentURI = data.getData();
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToLast();
if (l == 0) {
imagePath = cursor.getString(column_index_data);
}
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
BitmapDrawable bdrawable = new BitmapDrawable(this.getResources(), thumbnail);
if (l == 0) {
captureAadhar.setBackground(bdrawable);
}
saveImage(thumbnail);
Toast.makeText(SignUpActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();
}
如果我使用图库获取图片意味着我收到错误 "Bitmap too large to be uploaded into a texture"
如果我使用相机拍摄照片意味着出现错误
"Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=18253, uid=10257 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()"
public String saveImage(Bitmap myBitmap) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress( Bitmap.CompressFormat.JPEG, 90, bytes );
wallpaperDirectory = new File( Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY );
// have the object build the directory structure, if needed.
if (!wallpaperDirectory.exists()) {
wallpaperDirectory.mkdirs();
}
try {
f = new File( wallpaperDirectory, Calendar.getInstance().getTimeInMillis() + ".jpg" );
f.createNewFile();
FileOutputStream fo = new FileOutputStream( f );
fo.write( bytes.toByteArray() );
MediaScannerConnection.scanFile( this, new String[]{f.getPath()}, new String[]{"image/jpeg"}, null );
fo.close();
Log.d( "TAG", "File Saved::--->" + f.getAbsolutePath() );
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
至于加载大型 bimap,请阅读文档:https://developer.android.com/topic/performance/graphics/load-bitmap
基本上,您应该提供 inSampleSize 来加载负载缩放版本。不要尝试在不缩放的情况下解码大位图,这会失败。
试试这个,link 去图书馆
https://github.com/Tourenathan-G5organisation/SiliCompressor
/**
* Request Permission for writing to External Storage in 6.0 and up
*/
private void requestPermissions(int mediaType) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (mediaType == TYPE_IMAGE) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_STORAGE);
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_STORAGE_VID);
}
} else {
if (mediaType == TYPE_IMAGE) {
// Want to compress an image
dispatchTakePictureIntent();
} else if (mediaType == TYPE_VIDEO) {
// Want to compress a video
dispatchTakeVideoIntent();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
dispatchTakePictureIntent();
} else {
Toast.makeText(this, "You need to enable the permission for External Storage Write" +
" to test out this library.", Toast.LENGTH_LONG).show();
return;
}
break;
}
case MY_PERMISSIONS_REQUEST_WRITE_STORAGE_VID: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
dispatchTakeVideoIntent();
} else {
Toast.makeText(this, "You need to enable the permission for External Storage Write" +
" to test out this library.", Toast.LENGTH_LONG).show();
return;
}
break;
}
default:
}
}
private File createMediaFile(int type) throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fileName = (type == TYPE_IMAGE) ? "JPEG_" + timeStamp + "_" : "VID_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
type == TYPE_IMAGE ? Environment.DIRECTORY_PICTURES : Environment.DIRECTORY_MOVIES);
File file = File.createTempFile(
fileName, /* prefix */
type == TYPE_IMAGE ? ".jpg" : ".mp4", /* suffix */
storageDir /* directory */
);
// Get the path of the file created
mCurrentPhotoPath = file.getAbsolutePath();
Log.d(LOG_TAG, "mCurrentPhotoPath: " + mCurrentPhotoPath);
return file;
}
private void dispatchTakePictureIntent() {
/*Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");*/
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createMediaFile(TYPE_IMAGE);
} catch (IOException ex) {
// Error occurred while creating the File
Log.d(LOG_TAG, "Error occurred while creating the file");
}
// Continue only if the File was successfully created
if (photoFile != null) {
// Get the content URI for the image file
capturedUri = FileProvider.getUriForFile(this,
FILE_PROVIDER_AUTHORITY,
photoFile);
Log.d(LOG_TAG, "Log1: " + String.valueOf(capturedUri));
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedUri);
startActivityForResult(takePictureIntent, REQUEST_TAKE_CAMERA_PHOTO);
}
}
}
private void dispatchTakeVideoIntent() {
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
takeVideoIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
try {
takeVideoIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);
takeVideoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
capturedUri = FileProvider.getUriForFile(this,
FILE_PROVIDER_AUTHORITY,
createMediaFile(TYPE_VIDEO));
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedUri);
Log.d(LOG_TAG, "VideoUri: " + capturedUri.toString());
startActivityForResult(takeVideoIntent, REQUEST_TAKE_VIDEO);
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Method which will process the captured image
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//verify if the image was gotten successfully
if (requestCode == REQUEST_TAKE_CAMERA_PHOTO && resultCode == Activity.RESULT_OK) {
new ImageCompressionAsyncTask(this).execute(mCurrentPhotoPath,
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/Silicompressor/images");
} else if (requestCode == REQUEST_TAKE_VIDEO && resultCode == RESULT_OK) {
if (data.getData() != null) {
//create destination directory
File f = new File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/Silicompressor/videos");
if (f.mkdirs() || f.isDirectory())
//compress and output new video specs
new VideoCompressAsyncTask(this).execute(mCurrentPhotoPath, f.getPath());
}
}
}
class ImageCompressionAsyncTask 扩展了 AsyncTask {
Context mContext;
public ImageCompressionAsyncTask(Context context) {
mContext = context;
}
@Override
protected String doInBackground(String... params) {
String filePath = SiliCompressor.with(mContext).compress(params[0], new File(params[1]));
return filePath;
/*
Bitmap compressBitMap = null;
try {
compressBitMap = SiliCompressor.with(mContext).getCompressBitmap(params[0], true);
return compressBitMap;
} catch (IOException e) {
e.printStackTrace();
}
return compressBitMap;
*/
}
@Override
protected void onPostExecute(String s) {
/*
if (null != s){
imageView.setImageBitmap(s);
int compressHieght = s.getHeight();
int compressWidth = s.getWidth();
float length = s.getByteCount() / 1024f; // Size in KB;
String text = String.format("Name: %s\nSize: %fKB\nWidth: %d\nHeight: %d", "ff", length, compressWidth, compressHieght);
picDescription.setVisibility(View.VISIBLE);
picDescription.setText(text);
}
*/
File imageFile = new File(s);
compressUri = Uri.fromFile(imageFile);
//FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName()+ FILE_PROVIDER_EXTENTION, imageFile);
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), compressUri);
imageView.setImageBitmap(bitmap);
String name = imageFile.getName();
float length = imageFile.length() / 1024f; // Size in KB
int compressWidth = bitmap.getWidth();
int compressHieght = bitmap.getHeight();
String text = String.format(Locale.US, "Name: %s\nSize: %fKB\nWidth: %d\nHeight: %d", name, length, compressWidth, compressHieght);
picDescription.setVisibility(View.VISIBLE);
picDescription.setText(text);
} catch (IOException e) {
e.printStackTrace();
}
}
}
我想上传图片到服务器。将我的图像转换为位图,但仍然出现错误。位图太大,无法上传到纹理
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == this.RESULT_CANCELED) {
return;
}
if (requestCode == GALLERY) {
if (data != null) {
contentURI = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(contentURI, filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if (l == 0) {
imagePath = cursor.getString(columnIndex);
}
}
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
String path = saveImage(bitmap);
Toast.makeText(SignUpActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();
BitmapDrawable bdrawable = new BitmapDrawable(this.getResources(), bitmap);
if (l == 0) {
captureAadhar.setBackground(bdrawable);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
else if (requestCode == CAMERA) {
//if (checkPermissionREAD_EXTERNAL_STORAGE(this)) {
// do your stuff..
if (data != null) {
contentURI = data.getData();
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToLast();
if (l == 0) {
imagePath = cursor.getString(column_index_data);
}
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
BitmapDrawable bdrawable = new BitmapDrawable(this.getResources(), thumbnail);
if (l == 0) {
captureAadhar.setBackground(bdrawable);
}
saveImage(thumbnail);
Toast.makeText(SignUpActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();
}
如果我使用图库获取图片意味着我收到错误 "Bitmap too large to be uploaded into a texture"
如果我使用相机拍摄照片意味着出现错误
"Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=18253, uid=10257 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()"
public String saveImage(Bitmap myBitmap) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress( Bitmap.CompressFormat.JPEG, 90, bytes );
wallpaperDirectory = new File( Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY );
// have the object build the directory structure, if needed.
if (!wallpaperDirectory.exists()) {
wallpaperDirectory.mkdirs();
}
try {
f = new File( wallpaperDirectory, Calendar.getInstance().getTimeInMillis() + ".jpg" );
f.createNewFile();
FileOutputStream fo = new FileOutputStream( f );
fo.write( bytes.toByteArray() );
MediaScannerConnection.scanFile( this, new String[]{f.getPath()}, new String[]{"image/jpeg"}, null );
fo.close();
Log.d( "TAG", "File Saved::--->" + f.getAbsolutePath() );
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
至于加载大型 bimap,请阅读文档:https://developer.android.com/topic/performance/graphics/load-bitmap
基本上,您应该提供 inSampleSize 来加载负载缩放版本。不要尝试在不缩放的情况下解码大位图,这会失败。
试试这个,link 去图书馆 https://github.com/Tourenathan-G5organisation/SiliCompressor
/**
* Request Permission for writing to External Storage in 6.0 and up
*/
private void requestPermissions(int mediaType) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (mediaType == TYPE_IMAGE) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_STORAGE);
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_STORAGE_VID);
}
} else {
if (mediaType == TYPE_IMAGE) {
// Want to compress an image
dispatchTakePictureIntent();
} else if (mediaType == TYPE_VIDEO) {
// Want to compress a video
dispatchTakeVideoIntent();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
dispatchTakePictureIntent();
} else {
Toast.makeText(this, "You need to enable the permission for External Storage Write" +
" to test out this library.", Toast.LENGTH_LONG).show();
return;
}
break;
}
case MY_PERMISSIONS_REQUEST_WRITE_STORAGE_VID: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
dispatchTakeVideoIntent();
} else {
Toast.makeText(this, "You need to enable the permission for External Storage Write" +
" to test out this library.", Toast.LENGTH_LONG).show();
return;
}
break;
}
default:
}
}
private File createMediaFile(int type) throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fileName = (type == TYPE_IMAGE) ? "JPEG_" + timeStamp + "_" : "VID_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
type == TYPE_IMAGE ? Environment.DIRECTORY_PICTURES : Environment.DIRECTORY_MOVIES);
File file = File.createTempFile(
fileName, /* prefix */
type == TYPE_IMAGE ? ".jpg" : ".mp4", /* suffix */
storageDir /* directory */
);
// Get the path of the file created
mCurrentPhotoPath = file.getAbsolutePath();
Log.d(LOG_TAG, "mCurrentPhotoPath: " + mCurrentPhotoPath);
return file;
}
private void dispatchTakePictureIntent() {
/*Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");*/
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createMediaFile(TYPE_IMAGE);
} catch (IOException ex) {
// Error occurred while creating the File
Log.d(LOG_TAG, "Error occurred while creating the file");
}
// Continue only if the File was successfully created
if (photoFile != null) {
// Get the content URI for the image file
capturedUri = FileProvider.getUriForFile(this,
FILE_PROVIDER_AUTHORITY,
photoFile);
Log.d(LOG_TAG, "Log1: " + String.valueOf(capturedUri));
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedUri);
startActivityForResult(takePictureIntent, REQUEST_TAKE_CAMERA_PHOTO);
}
}
}
private void dispatchTakeVideoIntent() {
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
takeVideoIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
try {
takeVideoIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);
takeVideoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
capturedUri = FileProvider.getUriForFile(this,
FILE_PROVIDER_AUTHORITY,
createMediaFile(TYPE_VIDEO));
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedUri);
Log.d(LOG_TAG, "VideoUri: " + capturedUri.toString());
startActivityForResult(takeVideoIntent, REQUEST_TAKE_VIDEO);
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Method which will process the captured image
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//verify if the image was gotten successfully
if (requestCode == REQUEST_TAKE_CAMERA_PHOTO && resultCode == Activity.RESULT_OK) {
new ImageCompressionAsyncTask(this).execute(mCurrentPhotoPath,
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/Silicompressor/images");
} else if (requestCode == REQUEST_TAKE_VIDEO && resultCode == RESULT_OK) {
if (data.getData() != null) {
//create destination directory
File f = new File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/Silicompressor/videos");
if (f.mkdirs() || f.isDirectory())
//compress and output new video specs
new VideoCompressAsyncTask(this).execute(mCurrentPhotoPath, f.getPath());
}
}
}
class ImageCompressionAsyncTask 扩展了 AsyncTask {
Context mContext;
public ImageCompressionAsyncTask(Context context) {
mContext = context;
}
@Override
protected String doInBackground(String... params) {
String filePath = SiliCompressor.with(mContext).compress(params[0], new File(params[1]));
return filePath;
/*
Bitmap compressBitMap = null;
try {
compressBitMap = SiliCompressor.with(mContext).getCompressBitmap(params[0], true);
return compressBitMap;
} catch (IOException e) {
e.printStackTrace();
}
return compressBitMap;
*/
}
@Override
protected void onPostExecute(String s) {
/*
if (null != s){
imageView.setImageBitmap(s);
int compressHieght = s.getHeight();
int compressWidth = s.getWidth();
float length = s.getByteCount() / 1024f; // Size in KB;
String text = String.format("Name: %s\nSize: %fKB\nWidth: %d\nHeight: %d", "ff", length, compressWidth, compressHieght);
picDescription.setVisibility(View.VISIBLE);
picDescription.setText(text);
}
*/
File imageFile = new File(s);
compressUri = Uri.fromFile(imageFile);
//FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName()+ FILE_PROVIDER_EXTENTION, imageFile);
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), compressUri);
imageView.setImageBitmap(bitmap);
String name = imageFile.getName();
float length = imageFile.length() / 1024f; // Size in KB
int compressWidth = bitmap.getWidth();
int compressHieght = bitmap.getHeight();
String text = String.format(Locale.US, "Name: %s\nSize: %fKB\nWidth: %d\nHeight: %d", name, length, compressWidth, compressHieght);
picDescription.setVisibility(View.VISIBLE);
picDescription.setText(text);
} catch (IOException e) {
e.printStackTrace();
}
}
}