【问题标题】:Pick image from sd card, resize the image and save it back to sd card从 sd 卡中选择图像,调整图像大小并将其保存回 sd 卡
【发布时间】:2012-07-26 04:50:16
【问题描述】:

我正在开发一个应用程序,我需要从sd card 中选择一个图像并在图像视图中显示它。现在我希望用户通过单击一个按钮来减小/增加其宽度,然后将其保存回 sd 卡。

我已经完成了图像挑选并在 ui 上显示它。但无法找到如何调整它。任何人都可以建议我如何实现它。

【问题讨论】:

    标签: android image bitmap


    【解决方案1】:

    就在昨天我已经这样做了

    File dir=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
    Bitmap b= BitmapFactory.decodeFile(PATH_ORIGINAL_IMAGE);
    Bitmap out = Bitmap.createScaledBitmap(b, 320, 480, false);
    
    File file = new File(dir, "resize.png");
    FileOutputStream fOut;
    try {
        fOut = new FileOutputStream(file);
        out.compress(Bitmap.CompressFormat.PNG, 100, fOut);
        fOut.flush();
        fOut.close();
        b.recycle();
        out.recycle();               
    } catch (Exception e) {}
    

    别忘了回收你的bitmaps:它会节省内存。

    您还可以获取新创建的文件字符串的路径:newPath=file.getAbsolutePath();

    【讨论】:

    • BitmapFactory.decodeFile()............打开大尺寸图片时会抛出OOM异常,您需要使用“选项”才能打开,如果你这样做你会得到原始图像的缩小版............
    • 我需要缩小原始图像并保存它们,而不是更改后的图像......我在图库应用程序本身中注意到了这一点......我为大小为 6.33 MB 的图像添加了一些效果,效果后大小为 507 KB........大量信息丢失,我不希望这样......
    • 它工作正常,但如何保持图像质量。
    【解决方案2】:

    在 Kotlin 中没有 OutOfMemoryException 的解决方案

    fun resizeImage(file: File, scaleTo: Int = 1024) {
        val bmOptions = BitmapFactory.Options()
        bmOptions.inJustDecodeBounds = true
        BitmapFactory.decodeFile(file.absolutePath, bmOptions)
        val photoW = bmOptions.outWidth
        val photoH = bmOptions.outHeight
    
        // Determine how much to scale down the image
        val scaleFactor = Math.min(photoW / scaleTo, photoH / scaleTo)
    
        bmOptions.inJustDecodeBounds = false
        bmOptions.inSampleSize = scaleFactor
    
        val resized = BitmapFactory.decodeFile(file.absolutePath, bmOptions) ?: return
        file.outputStream().use {
            resized.compress(Bitmap.CompressFormat.JPEG, 75, it)
            resized.recycle()
        }
    }
    

    【讨论】:

      【解决方案3】:

      试试这个方法:

      public static Bitmap scaleBitmap(Bitmap bitmapToScale, float newWidth, float newHeight) {   
      if(bitmapToScale == null)
          return null;
      //get the original width and height
      int width = bitmapToScale.getWidth();
      int height = bitmapToScale.getHeight();
      // create a matrix for the manipulation
      Matrix matrix = new Matrix();
      
      // resize the bit map
      matrix.postScale(newWidth / width, newHeight / height);
      
      // recreate the new Bitmap and set it back
      return Bitmap.createBitmap(bitmapToScale, 0, 0, bitmapToScale.getWidth(), bitmapToScale.getHeight(), matrix, true);  
      } 
      

      【讨论】:

        【解决方案4】:
        【解决方案5】:

        我找到了这个有用的库来实现这个成就:https://github.com/hkk595/Resizer

        【讨论】:

          【解决方案6】:

          这里是我的静态方法:

          public static void resizeImageFile(File originalImageFile, File resizedImageFile, int maxSize) {
              Bitmap bitmap = BitmapFactory.decodeFile(originalImageFile.getAbsolutePath());
              Bitmap resizedBitmap;
              if (bitmap.getWidth() > bitmap.getHeight()) {
                  resizedBitmap = Bitmap.createScaledBitmap(bitmap, maxSize, maxSize * bitmap.getHeight() / bitmap.getWidth(), false);
              } else {
                  resizedBitmap = Bitmap.createScaledBitmap(bitmap, maxSize * bitmap.getWidth() / bitmap.getHeight(), maxSize, false);
              }
          
              FileOutputStream fileOutputStream;
              try {
                  fileOutputStream = new FileOutputStream(resizedImageFile);
                  resizedBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
                  fileOutputStream.flush();
                  fileOutputStream.close();
                  bitmap.recycle();
                  resizedBitmap.recycle();
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
          

          【讨论】:

            【解决方案7】:

            理想情况下,您应该使用多点触控而不是使用按钮来增加/减少宽度。 Here's 一个了不起的图书馆。一旦用户决定保存图像,图像转换矩阵必须永久存储(在您的 sqlite 数据库中)。下次用户打开图像时,您需要调用矩阵并将其应用于您的图像。

            其实我以前也做过。

            【讨论】:

              猜你喜欢
              • 2011-11-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-07-04
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多