当前位置: 首页 > 知识库问答 >
问题:

如何压缩位图图像?

高嘉树
2023-03-14

我想上传图像到服务器。将我的图像转换为位图,但仍然出错。位图太大,无法上传到纹理中

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

如果我得到图片使用画廊意味着我得到错误的位图太大,不能上传到纹理
如果我得到图片使用相机意味着得到错误的
造成:java.lang.安全例外:权限拒绝:阅读<-plhd--1/>MediaProvider uri内容://media/外部/图像/媒体从pid=18253,uid=10257需要android.permission.READ_EXTERNAL_STORAGE,或grantUriPersion()"

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 "";
}

共有2个答案

宰父跃
2023-03-14

对于加载大型BIMAP,请阅读文档:https://developer.android.com/topic/performance/graphics/load-bitmap

基本上,您应该提供inSampleSize以加载缩放版本。不要尝试在不缩放的情况下解码大位图,这将失败。

邬朗
2023-03-14

试试这个,链接到图书馆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());

        }
    }

}

扩展类ImageCompressionAsyncWG{

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

    }
}
 类似资料:
  • Android API提供了保存位图对象的方法。我创建了一个示例应用程序,它将jpeg图像(一些嘈杂的相机照片)加载到位图中,然后将其压缩回同一个文件。然后,再做5次。 显然,我的位图积累了压缩伪影。让我惊讶的是,这些伪影的数量以一种奇怪的方式取决于压缩的质量。当我将质量设置为100(我认为这是最好的质量)时,工件清晰可见。当我将质量降低到90时,工件的可视性明显降低。质量设置为80会给我最好的效

  • 我一直在计算图像的未压缩和压缩文件大小。这对我来说总是导致压缩图像比我预期的未压缩图像小。如果图像包含大量不同的颜色,则存储调色板会占用大量空间,还需要更多位来存储每个代码。然而,我的问题是,压缩方法是否可能导致比未压缩的RGB图像更大的文件。对于这种压缩方法仍然有用的、总共包含k种不同颜色的最小正方形RGB图像,其大小(像素)是多少?因此,我们想要找到,对于给定的k值,找到最小整数n,对于该整数

  • 我在Android上工作。我需要保存一个没有质量损失的位图。 我使用位图的方法进行了尝试,将质量设置为100。这对我不起作用,位图失去了太多的质量。我已经测试了JPEG和PNG格式。 我已经测试过将位图复制到,然后提取,并使用保存它。在这种情况下,我无法显示用这种方式保存的图像,我只看到一个空白页。 我的问题是,有没有办法在不压缩的情况下将位图保存在SD卡中? 编辑:这里我的代码的一部分 我检测到

  • 从pagespeed中,我只获得了图像链接和可能的优化(以字节为单位) 例如,我有大小为300kb的图像,对于该图像,pagespeed显示100kb 这只是一个图像,但我相信我会有很多图像压缩。所以,我如何通过传递字节或百分比作为参数或使用java中的任何其他计算(通过使用API或图像处理工具)来压缩图像,以便获得google建议的图像压缩版本。 提前谢谢。

  • 问题内容: 我正在通过wifi或移动网络通过网络发送图像,以将其存储在服务器中并再次检索。我已经这样做了,但是由于相机拍摄的图像太大,这使我的应用程序变慢,只是要指出我正在打开图库并从那里拍摄照片,而不是直接从应用程序拍摄照片。我注意到,从相机和图库中获取的来自whatsapp的图像已被压缩到大约50%。100kb。 目前,我的代码获取一个文件,并将其转换为字节,然后发送。这是获取文件并将其转换为

  • 我正在使用Python的Pillow库来读取图像文件。如何使用哈夫曼编码进行压缩和解压缩?以下是说明: 您已经获得了一组示例图像,您的目标是在不丢失任何可感知信息的情况下尽可能压缩它们——解压后,它们应该看起来与原始图像相同。图像本质上存储为一系列颜色点,其中每个点表示为红色、绿色和蓝色(rgb)的组合。rgb值的每个分量范围在0-255之间,因此例如:(100, 0, 200)表示紫色。使用固定