All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ofdrw.layout.element.Img Maven / Gradle / Ivy

The newest version!
package org.ofdrw.layout.element;

import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;

/**
 * 图片对象
 * 

* 为了防止与Image对象命名冲突采用Img缩写 *

* 绘制行为详见渲染器 {@link org.ofdrw.layout.engine.render.ImgRender} * * @author 权观宇 * @since 2020-02-03 03:34:31 */ public class Img extends Div { /** * 图片文件路径 */ private Path src; private Img() { // 图片对象不可拆分 this.setIntegrity(true); } /** * 构造图片对象 *

* 该构造器不会输入图片进行解析,直接将图片作为资源使用。 * * @param width 图片在页面内的宽度,单位毫米(mm) * @param height 图片在页面内的高度,单位毫米(mm) * @param src 图片路径(该构造器不会解析图片大小) * @throws IOException 读取异常 */ public Img(double width, double height, Path src) throws IOException { this(); if (src == null || Files.notExists(src)) { throw new IllegalArgumentException("图片文件为空或不存在"); } this.src = src; this.setWidth(width); this.setHeight(height); } /** * 创建图片Div *

* 图片宽度和高度以 每 5pix/mm (像素/毫米)的比例转换。 *

* 不建议使用该方式构造图片,图片的宽度和高度应该在由调用者手动指定 * 建议使用{@link Img#Img(double, double, java.nio.file.Path)}方法构造 * * @param src 图片路径 * @throws IOException 图片解析异常 * @deprecated {@link Img#Img(double, double, java.nio.file.Path)} */ @Deprecated public Img(Path src) throws IOException { this(); if (src == null || Files.notExists(src)) { throw new IllegalArgumentException("图片文件为空或不存在"); } this.src = src; parseImg(); } /** * 解析路径上的图片 * * @throws IOException 读取解析异常 */ private void parseImg() throws IOException { final File picture = src.toFile(); BufferedImage imgObj = null; try (FileInputStream fIn = new FileInputStream(picture)) { imgObj = ImageIO.read(fIn); } catch (IIOException e) { /* * 图片类型的问题,如果图片格式而是CMYK格式, * 使用ImageIO.read方法有时报javax.imageio.IIOException: Unsupported Image Type * 此处尝试将CMYK装换为 RGB。 */ imgObj = readImage(picture); } if (imgObj != null) { this.setWidth((double) imgObj.getWidth() / 5); this.setHeight((double) imgObj.getHeight() / 5); } } /** * 尝试读取图片文件为 BufferedImage *

* 首先尝试采用RGB读取,如果失败那么将CMYK进行色彩空间转化为RGB。 * * @param imageFile 图片文件 * @return BufferedImage * @throws IOException 操作或转换异常 * @author zwd */ public static BufferedImage readImage(File imageFile) throws IOException { try (ImageInputStream input = ImageIO.createImageInputStream(imageFile);) { Iterator readers = ImageIO.getImageReaders(input); if (readers == null || !readers.hasNext()) { return null; } ImageReader reader = (ImageReader) readers.next(); reader.setInput(input); BufferedImage image; try { // 尝试读取图片 (包括颜色的转换).RGB image = reader.read(0); } catch (IIOException e) { // 尝试将CMYK转换为RGB image = convertCMYK2RGB(reader); } return image; } } /** * 装换CMYK图片为RGB * * @param reader 图片解析器 * @return BufferedImage * @author zwd */ private static BufferedImage convertCMYK2RGB(ImageReader reader) throws IOException { // 读取Raster (没有颜色的转换) CMYK Raster raster = reader.readRaster(0, null); int w = raster.getWidth(); int h = raster.getHeight(); byte[] rgb = new byte[w * h * 3]; // 彩色空间转换 float[] Y = raster.getSamples(0, 0, w, h, 0, (float[]) null); float[] Cb = raster.getSamples(0, 0, w, h, 1, (float[]) null); float[] Cr = raster.getSamples(0, 0, w, h, 2, (float[]) null); float[] K = raster.getSamples(0, 0, w, h, 3, (float[]) null); for (int i = 0, imax = Y.length, base = 0; i < imax; i++, base += 3) { float k = 220 - K[i], y = 255 - Y[i], cb = 255 - Cb[i], cr = 255 - Cr[i]; double val = y + 1.402 * (cr - 128) - k; val = (val - 128) * .65f + 128; rgb[base] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff : (byte) (val + 0.5); val = y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128) - k; val = (val - 128) * .65f + 128; rgb[base + 1] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff : (byte) (val + 0.5); val = y + 1.772 * (cb - 128) - k; val = (val - 128) * .65f + 128; rgb[base + 2] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff : (byte) (val + 0.5); } raster = Raster.createInterleavedRaster( new DataBufferByte(rgb, rgb.length), w, h, w * 3, 3, new int[]{0, 1, 2}, null); ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); ColorModel cm = new ComponentColorModel(cs, false, true, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); return new BufferedImage(cm, (WritableRaster) raster, true, null); } public Path getSrc() { return src; } public Img setSrc(Path src) { this.src = src; return this; } /** * 不允许切分 */ @Override public Div[] split(double sHeight) { throw new RuntimeException("图片对象不支持分割操作"); } /** * 元素类型 *

* 关联绘制器:{@link org.ofdrw.layout.engine.render.ImgRender} * * @return Img */ @Override public String elementType() { return "Img"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy