Java 图片压缩占用内存大小

压缩图片(压缩一次,尽可能接近目标大小)

 public static void main(String[] args) {
    String sourceImagePath = "C:\\Users\\sam\\Desktop\\aa0f40db2c520cce9e3624a8978dc6a.jpg";
    String destinationImagePath = "C:\\Users\\sam\\Desktop\\image_compressed.jpg";
    int targetMemorySizeKB = 100; // 目标内存大小,单位为KB

    try {
      BufferedImage originalImage = ImageIO.read(new File(sourceImagePath));

      int originalSizeKB = getMemorySizeKB(originalImage);

      if (originalSizeKB <= targetMemorySizeKB) {
        System.out.println("Image is already smaller than target memory size.");
        return;
      }

      float compressRatio = (float) targetMemorySizeKB / (float) originalSizeKB;

      int newWidth = (int) (originalImage.getWidth() * Math.sqrt(compressRatio));
      int newHeight = (int) (originalImage.getHeight() * Math.sqrt(compressRatio));

      BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
      Graphics2D g = resizedImage.createGraphics();
      g.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
      g.dispose();
      File compressedImageFile = new File(destinationImagePath);
      ImageIO.write(resizedImage, "jpg", compressedImageFile);
      

    } catch (IOException e) {
      e.printStackTrace();
    }
  }

    private static int getMemorySizeKB(BufferedImage image) {
      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      try {
        ImageIO.write(image, "jpg", outputStream);
      } catch (IOException e) {
        e.printStackTrace();
        return 0;
      }
      return outputStream.size() / 1024; // 返回图片在内存中的大小,单位为KB
    }

递归压缩

  public static void main(String[] args) {
    String sourceImagePath = "C:\\Users\\sam\\Desktop\\aa0f40db2c520cce9e3624a8978dc6a.jpg";
    String destinationImagePath = "C:\\Users\\sam\\Desktop\\image_compressed.jpg";
    int targetSizeKB = 100; // 目标大小,单位为KB
    int diffSizeKB = 100; // 压缩内存的大小,单位为KB。压缩后文件的大小,如果小于该值,则不进行下次压缩
    int initSizeKB = Integer.MAX_VALUE; // 压缩前的大小
    int compressAfterSizeKB = 0; // 压缩后的大小

    try {
      BufferedImage originalImage = ImageIO.read(new File(sourceImagePath));
      int originalSizeKB = getMemorySizeKB(originalImage);
      initSizeKB = originalSizeKB;
      if (originalSizeKB <= targetSizeKB) {
        // Image is already smaller than target size.
        return;
      }

      float compressRatio = (float) targetSizeKB / (float) originalSizeKB;

      BufferedImage compressedImage = compressImage(originalImage, compressRatio);
      compressAfterSizeKB = getMemorySizeKB(compressedImage);

      while (compressAfterSizeKB > targetSizeKB && initSizeKB - compressAfterSizeKB > diffSizeKB) {
        compressRatio = 0.8f; // 减少10%左右的压缩比率,之后在计算时会开平方
        initSizeKB = compressAfterSizeKB;
        compressedImage = compressImage(compressedImage, compressRatio);
        compressAfterSizeKB = getMemorySizeKB(compressedImage);
      }

      File compressedImageFile = new File(destinationImagePath);
      ImageIO.write(compressedImage, "jpg", compressedImageFile);

    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  private static BufferedImage compressImage(BufferedImage image, float compressRatio) {
    int newWidth = (int) (image.getWidth() * Math.sqrt(compressRatio));
    int newHeight = (int) (image.getHeight() * Math.sqrt(compressRatio));

    BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = resizedImage.createGraphics();
    g.drawImage(image, 0, 0, newWidth, newHeight, null);
    g.dispose();

    return resizedImage;
  }

  private static int getMemorySizeKB(BufferedImage image) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try {
      ImageIO.write(image, "jpg", outputStream);
    } catch (IOException e) {
      e.printStackTrace();
      return 0;
    }
    return outputStream.size() / 1024; // 返回图片在内存中的大小,单位为KB
  }
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值