初遇 DPI

2017年05月16日 陈鑫杰

DPI

摘要: 处理图片大小,遇到以厘米为单位的宽高情况下。与平常不同时,该如何处理呢?

pdi-tips

DPI

维基

(英语:Dots Per Inch,每英寸点数)是一个量度单位,用于点阵数位影像,意思是指每一英寸长度中,取样或可显示或输出点的数目。

单位转换

1 英寸=2.54 厘米

1点 = 1/72英寸

1点 = 1/300英寸

问题

印刷业定制的图片剪辑功能,需要以 40 * 40 CM 或其他宽高规格来处理原始图片。请问应该怎么做?

解答

首先,印刷的通常分辨率为300dpi,就是一英寸300像素。即 DPI = 300;

所以,

假设宽度为 width,高度为 height,单位: CM;

得到,图片缩放后的最终宽高,

宽: width / 2.54 *DPI

高: height / 2.54 * DPI

代码

原图需要按指定宽高比例,配合页面选框进行裁剪。

裁剪后的图片,再进行以下步骤处理。

获取图片对象

File file = new File(filePath.toString());

转换获取 BufferedImage 对象

BufferedImage img = ImageIO.read(file)

获取图片宽高

double sourceW = img.getWidth();  
double sourceH = img.getHeight();

最终的宽高

int DPI = 300,  
width = 30, // cm  
height = 30; // cm  
double targetW = width / 2.54 * DPI;  
double targetH = height / 2.54 * DPI;  

计算压缩比(等比压缩)

double sx = (double) targetW / sourceW;  
double sy = (double) targetH / sourceH;

if (sx > sy) {  
	sx = sy;  
	targetW = (int) (sx * source.getWidth());  
} else if (sx < sy) {  
	sy = sx;  
	targetH = (int) (sy * source.getHeight());  
}  

空白画布

String type = "PNG";  
BufferedImage target = new BufferedImage(targetW, targetH, type);

绘制图片

Graphics2D g = target.createGraphics();  	g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);  
g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));  
g.dispose();  

转换 byte[]

byte[] result = null;  
ByteArrayOutputStream outStream = null;  
try {
	if (image != null) {
		outStream = new ByteArrayOutputStream();  
		ImageIO.write(image,format,outStream);  
		result = outStream.toByteArray();  
		}  
	} catch (Exception e) {  
		e.printStackTrace();  
	} finally {  
		if (outStream != null) {  
			try {  
				outStream.close();  
			} catch (IOException e) {  
				e.printStackTrace();  
			}  
		}  
	}  
	return result;  

存放新图片

BufferedOutputStream stream = null;
	try {
		File file = new File(outputFile);
		if (file.exists() && !isCover) {
			return Boolean.FALSE; // 源文件已经存在
		}
		FileOutputStream out = new FileOutputStream(file);
		stream = new BufferedOutputStream(out);
		stream.write(b);
	} catch (Exception e) {
		String fullStackTrace = ExceptionUtils.getStackTrace(e);
		LOGGER.error(fullStackTrace);
		return Boolean.FALSE;
	} finally {
		if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				String fullStackTrace = ExceptionUtils.getStackTrace(e);
				LOGGER.error(fullStackTrace);
				return Boolean.FALSE;
			}
		}
	}
	return Boolean.TRUE;

PS. 遇到新问题时,不要害怕,先分析再 Coding。

(转载本站文章请注明作者和出处 FoamValue – www.foamvalue.com ——=== 访问 404页面 寻找遗失儿童。 ===——