/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.alibaba.excel.util.StringUtils * com.jby.common.util.UniqueUtil * javax.xml.bind.JAXBElement * org.apache.commons.collections4.CollectionUtils * org.docx4j.TraversalUtil$CallbackImpl * org.docx4j.dml.GraphicData * org.docx4j.dml.picture.Pic * org.docx4j.dml.wordprocessingDrawing.Anchor * org.docx4j.dml.wordprocessingDrawing.Inline * org.docx4j.openpackaging.packages.WordprocessingMLPackage * org.docx4j.openpackaging.parts.Part * org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage * org.docx4j.openpackaging.parts.relationships.RelationshipsPart * org.docx4j.vml.CTImageData * org.docx4j.vml.CTShape * org.docx4j.vml.officedrawing.CTOLEObject * org.docx4j.wml.CTObject * org.docx4j.wml.Drawing * org.docx4j.wml.ObjectFactory * org.docx4j.wml.Pict * org.docx4j.wml.R * org.docx4j.wml.Text * org.slf4j.Logger * org.slf4j.LoggerFactory */ package com.jby.officecore.utils.finder; import com.alibaba.excel.util.StringUtils; import com.jby.common.util.UniqueUtil; import com.jby.officecore.domain.bo.ImageBO; import com.jby.officecore.domain.bo.ParseBO; import com.jby.officecore.enums.AttrEnum; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.ByteArrayInputStream; import java.io.File; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.imageio.ImageIO; import javax.xml.bind.JAXBElement; import org.apache.commons.collections4.CollectionUtils; import org.docx4j.TraversalUtil; import org.docx4j.dml.GraphicData; import org.docx4j.dml.picture.Pic; import org.docx4j.dml.wordprocessingDrawing.Anchor; import org.docx4j.dml.wordprocessingDrawing.Inline; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.Part; import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage; import org.docx4j.openpackaging.parts.relationships.RelationshipsPart; import org.docx4j.vml.CTImageData; import org.docx4j.vml.CTShape; import org.docx4j.vml.officedrawing.CTOLEObject; import org.docx4j.wml.CTObject; import org.docx4j.wml.Drawing; import org.docx4j.wml.ObjectFactory; import org.docx4j.wml.Pict; import org.docx4j.wml.R; import org.docx4j.wml.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DrawingPictFinder extends TraversalUtil.CallbackImpl { private static final Logger log = LoggerFactory.getLogger(DrawingPictFinder.class); private final WordprocessingMLPackage wordMlPackage; private final ParseBO parseBO; private static final double CROP_SCALE = 1.52587890625; public DrawingPictFinder(WordprocessingMLPackage wordMlPackage, ParseBO parseBO) { this.wordMlPackage = wordMlPackage; this.parseBO = parseBO; } public List apply(Object o) { List contentList; List anyAndAny; R r; if (o instanceof Drawing && ((Drawing)o).getParent() instanceof R) { RelationshipsPart relationshipsPart = this.wordMlPackage.getMainDocumentPart().getRelationshipsPart(); Drawing drawing = (Drawing)o; List anchorOrInline = drawing.getAnchorOrInline(); if (CollectionUtils.isNotEmpty((Collection)anchorOrInline)) { Object anchorOrInlineObj = anchorOrInline.get(0); GraphicData graphicData = null; long cx = 0L; long cy = 0L; if (anchorOrInlineObj instanceof Inline) { Inline inline = (Inline)anchorOrInlineObj; graphicData = inline.getGraphic().getGraphicData(); cx = inline.getExtent().getCx(); cy = inline.getExtent().getCy(); } else if (anchorOrInlineObj instanceof Anchor) { Anchor anchor = (Anchor)anchorOrInlineObj; graphicData = anchor.getGraphic().getGraphicData(); cx = anchor.getExtent().getCx(); cy = anchor.getExtent().getCy(); } if (Objects.nonNull(graphicData) && "http://schemas.openxmlformats.org/drawingml/2006/picture".equals(graphicData.getUri())) { for (Object object : graphicData.getAny()) { String path; JAXBElement jaxbElement; if (!(object instanceof JAXBElement) || !((jaxbElement = (JAXBElement)object).getValue() instanceof Pic)) continue; Pic pic = (Pic)jaxbElement.getValue(); String imageDataId = null; int cropLeft = 0; int cropTop = 0; int cropRight = 0; int cropBottom = 0; int rotation = 0; if (Objects.nonNull(pic.getBlipFill())) { if (Objects.nonNull(pic.getBlipFill().getBlip())) { imageDataId = pic.getBlipFill().getBlip().getEmbed(); } if (Objects.nonNull(pic.getBlipFill().getSrcRect())) { cropLeft = pic.getBlipFill().getSrcRect().getL(); cropTop = pic.getBlipFill().getSrcRect().getT(); cropRight = pic.getBlipFill().getSrcRect().getR(); cropBottom = pic.getBlipFill().getSrcRect().getB(); } if (Objects.nonNull(pic.getSpPr()) && Objects.nonNull(pic.getSpPr().getXfrm())) { rotation = pic.getSpPr().getXfrm().getRot(); } } Map map = this.dealCropRotate(imageDataId, cx, cropLeft, cropTop, cropRight, cropBottom, rotation); Object widthObj = map.get(AttrEnum.WIDTH.getAttr()); Object heightObj = map.get(AttrEnum.HEIGHT.getAttr()); Object pathObj = map.get("imagePath"); double width = Objects.nonNull(widthObj) ? Double.parseDouble(widthObj.toString()) : (double)Math.round((double)cx / 9525.0); double height = Objects.nonNull(heightObj) ? Double.parseDouble(heightObj.toString()) : (double)Math.round((double)cy / 9525.0); Part part = relationshipsPart.getPart(imageDataId); if (Objects.nonNull(pathObj)) { path = String.valueOf(pathObj); } else if (Objects.nonNull(part)) { path = part.getPartName().getURI().getPath(); } else { log.warn("\u65e0\u6cd5\u83b7\u53d6\u56fe\u7247Part\uff0cimageDataId={}", (Object)imageDataId); continue; } String imagePlaceholder = this.parseBO.getImagePlaceholder(imageDataId); ImageBO imageBO = new ImageBO().setWidth(width).setHeight(height).setPictureUrl(path); this.parseBO.getImageMap().put(imagePlaceholder, imageBO); R r2 = (R)drawing.getParent(); List contentList2 = r2.getContent(); int drawingIndex = contentList2.indexOf(drawing); if (drawingIndex != -1) { Text text = new ObjectFactory().createText(); text.setValue(imagePlaceholder); contentList2.set(drawingIndex, text); continue; } log.warn("\u672a\u627e\u5230drawing\u5bf9\u8c61\u5728\u7236\u5143\u7d20\u4e2d\u7684\u7d22\u5f15\uff0c\u8df3\u8fc7\u66ff\u6362\u64cd\u4f5c"); } } } } if (o instanceof Pict && ((Pict)o).getParent() instanceof R) { Pict pict = (Pict)o; r = (R)pict.getParent(); anyAndAny = pict.getAnyAndAny(); contentList = r.getContent(); int pictIndex = contentList.indexOf(pict); if (pictIndex != -1) { this.dealCtShape(anyAndAny, r, pictIndex); } } if (o instanceof CTObject && ((CTObject)o).getParent() instanceof R) { CTObject ctObject = (CTObject)o; r = (R)ctObject.getParent(); anyAndAny = ctObject.getAnyAndAny(); contentList = r.getContent(); int ctObjectIndex = contentList.indexOf(ctObject); if (ctObjectIndex != -1) { this.dealCtShape(anyAndAny, r, ctObjectIndex); } } return null; } private String extractValue(String style, String property) { if (style == null || property == null) { return null; } String regex = "\\b" + Pattern.quote(property) + "\\s*:\\s*([\\d.]+[a-zA-Z]*)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(style); if (matcher.find()) { return matcher.group(1); } return null; } private void dealCtShape(List anyAndAny, R r, int pictIndex) { String ctOleObjectRid = anyAndAny.stream().filter(f -> f instanceof JAXBElement && ((JAXBElement)f).getValue() instanceof CTOLEObject).map(f -> ((CTOLEObject)((JAXBElement)f).getValue()).getId()).filter(Objects::nonNull).findFirst().orElse(null); if (Objects.nonNull(ctOleObjectRid) && Objects.nonNull(this.parseBO.getMathTypeMap().get(this.parseBO.getMathTypePlaceholder(ctOleObjectRid)))) { Text text = new ObjectFactory().createText(); text.setValue(this.parseBO.getMathTypePlaceholder(ctOleObjectRid)); r.getContent().set(pictIndex, text); } else if (Objects.isNull(ctOleObjectRid) || Objects.isNull(this.parseBO.getMathTypeMap().get(this.parseBO.getMathTypePlaceholder(ctOleObjectRid)))) { if (Objects.nonNull(ctOleObjectRid)) { this.parseBO.getMathTypeMap().remove(this.parseBO.getMathTypePlaceholder(ctOleObjectRid)); } for (Object object : anyAndAny) { String path; double heightPx; double widthPx; if (!(object instanceof JAXBElement) || !(((JAXBElement)object).getValue() instanceof CTShape)) continue; CTShape ctShape = (CTShape)((JAXBElement)object).getValue(); String width = this.extractValue(ctShape.getStyle(), "width"); String height = this.extractValue(ctShape.getStyle(), "height"); CTImageData ctImageData = ctShape.getEGShapeElements().stream().filter(f -> f.getValue() instanceof CTImageData).map(m -> (CTImageData)m.getValue()).findFirst().orElse(null); if (!Objects.nonNull(ctImageData) || !StringUtils.isNotBlank((CharSequence)width) || !StringUtils.isNotBlank((CharSequence)height)) continue; String ctImageDataId = ctImageData.getId(); long cx = 0L; try { double widthPtIn = Double.parseDouble(width.substring(0, width.length() - 2)); if (width.endsWith("pt")) { cx = Math.round(widthPtIn * 12700.0); } else if (width.endsWith("in")) { cx = Math.round(widthPtIn * 914400.0); } } catch (NumberFormatException ignored) { log.error("extractWidth error"); } int cropLeft = this.parseVmlCrop(ctImageData.getCropleft()); int cropTop = this.parseVmlCrop(ctImageData.getCroptop()); int cropRight = this.parseVmlCrop(ctImageData.getCropright()); int cropBottom = this.parseVmlCrop(ctImageData.getCropbottom()); String rotRaw = this.extractValue(ctShape.getStyle(), "rotation"); int rotation = rotRaw == null ? 0 : (int)Math.round((double)Long.parseLong(rotRaw.replaceAll("[^\\d-]", "")) * 0.91552734375); Map map = this.dealCropRotate(ctImageDataId, cx, cropLeft, cropTop, cropRight, cropBottom, rotation); Object widthObj = map.get(AttrEnum.WIDTH.getAttr()); Object heightObj = map.get(AttrEnum.HEIGHT.getAttr()); Object pathObj = map.get("imagePath"); if (Objects.nonNull(widthObj) && Objects.nonNull(heightObj)) { widthPx = (Double)map.get(AttrEnum.WIDTH.getAttr()); heightPx = (Double)map.get(AttrEnum.HEIGHT.getAttr()); } else { widthPx = Double.parseDouble(width.replaceAll("pt|in", "")); if (width.endsWith("pt")) { widthPx = Math.round(widthPx * 96.0 / 72.0); } else if (width.endsWith("in")) { widthPx = Math.round(widthPx * 96.0); } heightPx = Double.parseDouble(height.replaceAll("pt|in", "")); if (height.endsWith("pt")) { heightPx = heightPx * 96.0 / 72.0; } else if (height.endsWith("in")) { heightPx *= 96.0; } } RelationshipsPart relationshipsPart = this.wordMlPackage.getMainDocumentPart().getRelationshipsPart(); Part part = relationshipsPart.getPart(ctImageDataId); if (Objects.nonNull(pathObj)) { path = String.valueOf(pathObj); } else if (Objects.nonNull(part)) { path = part.getPartName().getURI().getPath(); } else { log.warn("\u65e0\u6cd5\u83b7\u53d6\u8001\u7248VML\u56fe\u7247Part\uff0cctImageDataId={}", (Object)ctImageDataId); continue; } ImageBO imageBO = new ImageBO().setWidth(widthPx).setHeight(heightPx).setPictureUrl(path); String imagePlaceholder = this.parseBO.getImagePlaceholder(ctImageDataId); this.parseBO.getImageMap().put(imagePlaceholder, imageBO); Text text = new ObjectFactory().createText(); text.setValue(imagePlaceholder); r.getContent().set(pictIndex, text); break; } } } private Map dealCropRotate(String imageDataId, long cx, int cropLeft, int cropTop, int cropRight, int cropBottom, int rotation) { HashMap result = new HashMap(); try { if (Objects.nonNull(imageDataId)) { boolean isRotate; boolean isCrop = cropLeft > 0 || cropTop > 0 || cropRight > 0 || cropBottom > 0; boolean bl = isRotate = rotation != 0; if (isCrop || isRotate) { RelationshipsPart relationshipsPart = this.wordMlPackage.getMainDocumentPart().getRelationshipsPart(); Part part = relationshipsPart.getPart(imageDataId); BinaryPartAbstractImage imagePart = (BinaryPartAbstractImage)part; BufferedImage targetImage = ImageIO.read(new ByteArrayInputStream(imagePart.getBytes())); if (isCrop) { targetImage = this.cropImage(targetImage, cropLeft, cropTop, cropRight, cropBottom); } if (isRotate) { targetImage = this.rotateImage(targetImage, rotation, cx, result); } if (Objects.nonNull(targetImage)) { String formatName = this.getFormatName(imagePart); String path = "/word/media/" + UniqueUtil.getUuid() + "." + formatName; ImageIO.write((RenderedImage)targetImage, formatName, new File(this.parseBO.getTempDir() + "/temp" + path)); result.put("imagePath", path); } } } } catch (Exception e) { log.error("\u5904\u7406\u56fe\u7247\u88c1\u526a\u4e0e\u65cb\u8f6c\u5f02\u5e38", (Throwable)e); } return result; } private String getFormatName(BinaryPartAbstractImage imagePart) { String contentType = imagePart.getContentType(); String formatName = contentType.contains("png") ? "png" : (contentType.contains("jpeg") ? "jpeg" : (contentType.contains("gif") ? "gif" : (contentType.contains("bmp") ? "bmp" : "png"))); return formatName; } public BufferedImage cropImage(BufferedImage originalImage, int srcRectL, int srcRectT, int srcRectR, int srcRectB) { double leftRatio = srcRectL < 0 ? 0.0 : (double)srcRectL / 100000.0; double topRatio = srcRectT < 0 ? 0.0 : (double)srcRectT / 100000.0; double rightRatio = srcRectR < 0 ? 0.0 : (double)srcRectR / 100000.0; double bottomRatio = srcRectB < 0 ? 0.0 : (double)srcRectB / 100000.0; int originalWidth = originalImage.getWidth(); int originalHeight = originalImage.getHeight(); int left = (int)Math.floor(leftRatio * (double)originalWidth); int top = (int)Math.floor(topRatio * (double)originalHeight); int right = (int)Math.floor(rightRatio * (double)originalWidth); int bottom = (int)Math.floor(bottomRatio * (double)originalHeight); int cropWidth = Math.max(1, originalWidth - left - right); int cropHeight = Math.max(1, originalHeight - top - bottom); if (left < 0 || top < 0 || left + cropWidth > originalWidth || top + cropHeight > originalHeight) { log.error("\u88c1\u526a\u533a\u57df\u65e0\u6548\u6216\u8d85\u51fa\u56fe\u7247\u8fb9\u754c"); } return originalImage.getSubimage(left, top, cropWidth, cropHeight); } private BufferedImage rotateImage(BufferedImage originalImage, long rotation, long currentCx, Map result) { int origWidth = originalImage.getWidth(); int origHeight = originalImage.getHeight(); if (origWidth <= 0 || origHeight <= 0) { log.error("\u56fe\u7247\u533a\u57df\u65e0\u6548"); } double emuPerPx = (double)currentCx / (double)origWidth; if (currentCx == 0L) { emuPerPx = 9525.0; } double degrees = (double)rotation / 60000.0; double radians = Math.toRadians(degrees); double sin = Math.abs(Math.sin(radians)); double cos = Math.abs(Math.cos(radians)); double TOLERANCE = 1.0E-10; if (sin < 1.0E-10) { sin = 0.0; } if (cos < 1.0E-10) { cos = 0.0; } int newWidth = (int)Math.ceil((double)origWidth * cos + (double)origHeight * sin); int newHeight = (int)Math.ceil((double)origWidth * sin + (double)origHeight * cos); newWidth = Math.max(1, newWidth); newHeight = Math.max(1, newHeight); int superSampleFactor = 4; int ssWidth = origWidth * superSampleFactor; int ssHeight = origHeight * superSampleFactor; int ssNewW = newWidth * superSampleFactor; int ssNewH = newHeight * superSampleFactor; int imgType1 = originalImage.getType() == 0 ? 2 : originalImage.getType(); BufferedImage highResOriginal = new BufferedImage(ssWidth, ssHeight, imgType1); Graphics2D g2dHighRes = highResOriginal.createGraphics(); this.configureGraphics2D(g2dHighRes); g2dHighRes.drawImage(originalImage, 0, 0, ssWidth, ssHeight, null); g2dHighRes.dispose(); int imgType2 = highResOriginal.getType() == 0 ? 2 : highResOriginal.getType(); BufferedImage rotatedSuperSample = new BufferedImage(ssNewW, ssNewH, imgType2); Graphics2D g2dRotated = rotatedSuperSample.createGraphics(); if (highResOriginal.getType() == 2) { g2dRotated.setComposite(AlphaComposite.Clear); g2dRotated.fillRect(0, 0, ssNewW, ssNewH); g2dRotated.setComposite(AlphaComposite.SrcOver); } else { g2dRotated.setColor(Color.WHITE); g2dRotated.fillRect(0, 0, ssNewW, ssNewH); } g2dRotated.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2dRotated.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2dRotated.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2dRotated.translate((double)ssNewW / 2.0, (double)ssNewH / 2.0); g2dRotated.rotate(radians); g2dRotated.drawImage((Image)highResOriginal, -ssWidth / 2, -ssHeight / 2, null); g2dRotated.dispose(); BufferedImage rotatedImage = new BufferedImage(newWidth, newHeight, rotatedSuperSample.getType() == 0 ? 2 : rotatedSuperSample.getType()); Graphics2D g2dFinal = rotatedImage.createGraphics(); this.configureGraphics2D(g2dFinal); g2dFinal.drawImage(rotatedSuperSample, 0, 0, newWidth, newHeight, null); g2dFinal.dispose(); long newCx = Math.round((double)newWidth * emuPerPx); long newCy = Math.round((double)newHeight * emuPerPx); double newWidthPx = Math.round((double)newCx / 9525.0); double newHeightPx = Math.round((double)newCy / 9525.0); result.put(AttrEnum.WIDTH.getAttr(), newWidthPx); result.put(AttrEnum.HEIGHT.getAttr(), newHeightPx); return rotatedImage; } private void configureGraphics2D(Graphics2D g2d) { g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } private int parseVmlCrop(String vmlCrop) { if (vmlCrop == null || StringUtils.isBlank((CharSequence)vmlCrop)) { return 0; } String clean = vmlCrop.trim().replaceAll("[fF]$", ""); try { int value = Integer.parseInt(clean); return (int)Math.round((double)value * 1.52587890625); } catch (NumberFormatException e) { return 0; } } }