java graphics2d 旋转图片

由于iphone拍出来的照片存在旋转的问题,当然在iphone上查看是没有问题的,但是如果是在安卓手机上或者使用windows 图片查看器就会发现图片是旋转90度的。有一些安卓手机拍出来的照片也是旋转的,比如三星的那个曲屏手机。所以需要程序去把图片旋转过来,变成正的,保证体验一致。

原理是通过metadata-extractor去检测图片的EXIF信息,获取图片的ORIENTATION信息

 <dependency>
       <groupId>com.drewnoakes</groupId>
       <artifactId>metadata-extractor</artifactId>
       <version>2.9.0</version>
 </dependency>

读取代码如下:

     public static int readImgExifOrientation(InputStream in){

		try {
			if (in.markSupported()) {
				Metadata metadata = ImageMetadataReader.readMetadata(in);
				in.reset();//重置流
				ExifIFD0Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
				if (directory != null) {

					int tag = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
					logger.debug("方向: " + tag);
					ExifIFD0Descriptor descriptor = new ExifIFD0Descriptor(directory);
					logger.debug(descriptor.getOrientationDescription());

					return tag;
				}
			}else {
				throw new RuntimeException("必须使用支持mark 的input stream");
			}
		} catch (Exception e) {
			logger.error("读取图片方向失败",e);
		}
		return 0;
	}

返回的tag值对应了一个旋转的角度。通过自己写的一个方法去对应。具体对应的是多少度可以去查看这个库的文档。这里只列举了这几个。

    private static float getRotate(int tag){
		switch (tag){
			case 3:
				return 180;
			case 5:
				return 270;
			case 6:
				return 90;
			case 7:
				return 270;
			case 8:
				return 90;
			default:return 0;
		}
	}

得到旋转的角度之后,我们就可以调用api去将图片再旋转回来。

     public static InputStream rotate(InputStream in,int tag,String suffix) throws Exception{
		double theta = Math.toRadians(getRotate(tag));
		if (theta == 0) {//不需要旋转
			return in;
		}
		if(suffix!=null){
			suffix = suffix.replaceAll("\\.", "");
		}else {
			suffix = ".jpg";
		}
		BufferedImage oldImg = ImageIO.read(in);
		int w = oldImg.getWidth();
		int h = oldImg.getHeight();
		BufferedImage newImg = new BufferedImage(h,w,oldImg.getColorModel().getTransparency());
		Graphics2D g2d =newImg.createGraphics();
		g2d.setRenderingHint(
				RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g2d.rotate(theta, w/2, h/2); //旋转
		g2d.drawImage(oldImg,  h,0, null);
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		ImageIO.write(newImg, suffix, out);
		g2d.dispose();
		return new ByteArrayInputStream(out.toByteArray());
	}

使用java2d中的旋转之后发现左下角会出现黑边,图片被截取。另外网上很多人写的代码都是创建一张跟原图相同宽高的图片,然后再旋转,但是这样操作之后黑边会出现在国内人边,并且图片也会被截取。

找了一些原因,由于对图形部分研究不深,无法解决。一直觉得做图形的都是牛比人物。最后采用另外一个库thumbnailator。

        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>

这个库操作很简单,两句话就可以进行旋转。

    public static InputStream rotate(InputStream in,int tag,String suffix) throws Exception{
		double theta = getRotate(tag);
		if (theta == 0) {//不需要旋转
			return in;
		}
		if(suffix!=null){
			suffix = suffix.replaceAll("\\.", "");
		}else {
			suffix = ".jpg";
		}
		BufferedImage oldImg = ImageIO.read(in);
		int w = oldImg.getWidth();
		int h = oldImg.getHeight();
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		Thumbnails.of(oldImg).size(h,w).rotate(theta).outputFormat(suffix).toOutputStream(out);
		return new ByteArrayInputStream(out.toByteArray());
	}

 

转载于:https://my.oschina.net/qzzsunly/blog/702310

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值