如何压缩位图图像?

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

    }
}