zoukankan      html  css  js  c++  java
  • 图片裁切中遇到的小问题

    今天使用ImageIO实现裁切图片,遇到了一个错误:

    Not a JPEG file: starts with 0xff 0xd9

    因为要获取裁剪原点和裁切尺寸,所以我想获取图片宽高,用较小的一个作为裁切尺寸,进而得到一个正方形的图,所以就有了如下代码:

    File imageFile = new File(imageFileFullPath);
    FileInputStream imageFileInputStream = new FileInputStream(imageFile);
    // 获取原始图片,用于读取宽和高
    BufferedImage bufferedImage = ImageIO.read(imageFileInputStream);
    int imageWidth = bufferedImage.getWidth();
    int imageHeight = bufferedImage.getHeight();
    if(imageWidth == imageHeight) {
    //直接返回,不进行裁切
    }
    // 取较小的数值为裁剪尺寸
    int clipSize = imageWidth > imageHeight ? imageHeight : imageWidth;

    然而在裁切并输出结果时,又用到了这样的代码:

    Iterator<ImageReader> readerIt = ImageIO.getImageReadersByFormatName("jpg");
    ImageReader reader = readerIt.next();
    // 获取图片流
    ImageInputStream imageInputStream = ImageIO.createImageInputStream(imageFileInputStream);
    reader.setInput(imageInputStream, true);
    Rectangle rectangle = new Rectangle(0, 0, clipSize, clipSize);
            
    param.setSourceRegion(rectangle);
            
    //读取选取的区域
    BufferedImage clipedImage = reader.read(0, param);

    没过多久我就找到了解决办法,以至于我认为导致错误的原因就是定义了两个BufferedImage。这个解决方法是:去掉获取宽高的BufferedImage对象的定义,改用reader获取原始图片尺寸:

    int imageWidth = reader.getWidth(0);
    int imageHeight = reader.getHeight(0);

    这样就能够正常运行了。以目前掌握的知识还不能理解文章开头提到的错误是如何出现的,因为去掉一个BufferedImage的定义就能够正常裁切,所以我想是不是不能定义两个BufferedImage对象的原因,直到我尝试了以下方法:

    BufferedImage clipedImage = bufferedImage.getSubimage(0, 0, clipSize, clipSize);

    取代上面的那一大段代码,同样用到了两个BufferedImage对象,这种形式就能够很好地去执行。

    之后我又继续思考可能导致这个错误的原因,发现了一个可疑之处:

    // 获取原始图片,用于读取宽和高
    BufferedImage bufferedImage = ImageIO.read(imageFileInputStream);

     这个imageFileInputStream对象是已经读取到的图片对象,而ImageIO的read方法还有一个参数就是File,所以我替换了一下:

    BufferedImage bufferedImage = ImageIO.read(imageFile);

    竟然也裁切成功了!不过还是没有从根本上理解错误出现的原因,暂且记下,以后慢慢发现。

    图片裁切的代码参考了:

    http://www.oschina.net/code/snippet_857368_14826

    再贴一个BufferedImage相关的好文:

    http://blog.163.com/yuhua_kui/blog/static/9679964420139118203818/

  • 相关阅读:
    浅谈Java 8的新特性和使用场景
    Oracle下通过EXPDP导出某用户下的所有表,实例
    官网下载I.MX6参考手册
    TFTP服务开启
    二、 U-Boot 命令使用
    CP15协处理器
    Linux内核配置Kconfig语法
    M.2接口是如何辨别插入的SSD是SATA协议还是NVME协议?
    SSH 服务开启
    一 、 UBOOT简介
  • 原文地址:https://www.cnblogs.com/leemup/p/5391309.html
Copyright © 2011-2022 走看看