Java原生Image和Google开源框架Thumbnails处理图片

业务功能包括了重新调整大小,bmp转png或gif,300kb转gif可以实现10kb以下,但是在飞腾CPU+麒麟操作系统中出现了图片模糊的问题,而在龙芯CPU+麒麟上就是正常的,由于过于玄学,花了一天的时间后决定换一个压缩图片的方法。

=====================原生处理方式===============

public static String getPreviewPngBase64(String base64Code, int width, int height) {
		BufferedImage srcImage;
		byte[] data = null;
		try {
			byte[] buffer = Base64.decodeBase64(base64Code);
			ByteArrayInputStream in = new ByteArrayInputStream(buffer);
			srcImage = ImageIO.read(in);
			data = resize(srcImage, width, height);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return GetBaseByByte(data);
}
private static byte[] resize(BufferedImage source, int targetW,int targetH) {
		byte[] datas=null;
		try {
			IndexColorModel cm = createIndexColorModel();		
			BufferedImage target = null;
			ImageIcon imageIcon = new ImageIcon(source); 
			double sx = (double) targetW / source.getWidth();
			double sy = (double) targetH / source.getHeight();
			if (sx > sy) {
				sx = sy;
				targetW = (int) (sx * source.getWidth());
			} else {
				sy = sx;
				targetH = (int) (sy * source.getHeight());
			}

			target= new BufferedImage(  
					targetW, targetH,  
	                BufferedImage.TYPE_BYTE_INDEXED,cm);  
			Graphics2D g = target.createGraphics(); 
			g.drawImage(imageIcon.getImage(), 0, 0,  targetW,targetH,
	                imageIcon.getImageObserver()); 
            //将白色像素0xFFFFFFFF或者rgb在color_range内改为0x00FFFFFF透明像素
	        for (int j1 = target.getMinY(); j1 < target  
	                .getHeight(); j1++) {  
	            for (int j2 = target.getMinX(); j2 < target  
	                    .getWidth(); j2++) {  
	                int rgb = target.getRGB(j2, j1);  
	                if((rgb==Color.white.getRGB())||colorInRange(rgb)) { 
	                    rgb=0x00FFFFFF;
	                }
	                target.setRGB(j2, j1, rgb);  
	            }  
	        }   
	        g.drawImage(target, 0, 0, imageIcon.getImageObserver());  
			ByteArrayOutputStream out=new ByteArrayOutputStream();
			ImageIO.write(target, "gif", out);
			datas=out.toByteArray();
	        out.close();
			g.dispose();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return datas;
}

private static int color_range = 220;  
private static boolean colorInRange(int color) {  
    int red = (color & 0xff0000) >> 16;  
    int green = (color & 0x00ff00) >> 8;  
    int blue = (color & 0x0000ff);  
    return red >= color_range && green >= color_range && blue >= color_range;
}  
       

=============Thumbnails=================

用了Thumbnails后颜色正常了,但是又遇到天坑,转出来的图片到本司的软件中底色是透明的,而在web浏览器上并不是,苦思冥想半天也没想通是为什么,第二天突然顿悟可能是本司软件又对图片做了一次转透明的处理。那应该是转出来的图片确实不是透明的,跟原生压缩做一次对比发现确实是这样,原来是需要在builder中设置imageType,没设置时是按照RGB来输出的,少了alpha量,所以遍历RGB转为0x00FFFFFF的操作输出是就被输出为了0xFFFFFF,从而导致底色没有转成透明。

Thumbnails.of(in2).imageType(BufferedImage.TYPE_INT_ARGB).size(targetW, targetH).asBufferedImage();
public static String getPreviewGifBase64(String base64Code, int targetW, int targetH) {
		BufferedImage srcImage;
		byte[] datas = null;
		try {
			byte[] buffer = Base64.decodeBase64(base64Code);
			ByteArrayInputStream in = new ByteArrayInputStream(buffer);
			//不能重复读
			ByteArrayInputStream in2 = new ByteArrayInputStream(buffer);
			srcImage = ImageIO.read(in);
			double sx = (double) targetW / srcImage.getWidth();
			double sy = (double) targetH / srcImage.getHeight();
			if (sx > sy) {
				sx = sy;
				targetW = (int) (sx * srcImage.getWidth());
			} else {
				sy = sx;
				targetH = (int) (sy * srcImage.getHeight());
			}
			//输出携带alpha量的ARGB格式
			BufferedImage image = Thumbnails.of(in2).imageType(BufferedImage.TYPE_INT_ARGB).size(targetW, targetH).asBufferedImage();
			//设置透明
			setColor(image);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ImageIO.write(image, "gif", out);
			datas=out.toByteArray();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return GetBaseByByte(datas);
	};

 

你可能感兴趣的:(java)