Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Copyright 2007-2008, Plutext Pty Ltd.
- *
- * This file is part of docx4j.
- docx4j is licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package org.docx4j.openpackaging.parts.WordprocessingML;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.net.URL;
- import org.apache.xmlgraphics.image.loader.ImageInfo;
- import org.apache.xmlgraphics.image.loader.ImageSize;
- import org.docx4j.UnitsOfMeasurement;
- import org.docx4j.dml.picture.Pic;
- import org.docx4j.dml.wordprocessingDrawing.Inline;
- import org.docx4j.model.structure.PageDimensions;
- import org.docx4j.openpackaging.Base;
- import org.docx4j.openpackaging.contenttype.ContentTypeManager;
- import org.docx4j.openpackaging.contenttype.ContentTypes;
- import org.docx4j.openpackaging.exceptions.InvalidFormatException;
- import org.docx4j.openpackaging.packages.OpcPackage;
- import org.docx4j.openpackaging.packages.PresentationMLPackage;
- import org.docx4j.openpackaging.packages.SpreadsheetMLPackage;
- import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
- import org.docx4j.openpackaging.parts.ExternalTarget;
- import org.docx4j.openpackaging.parts.Part;
- import org.docx4j.openpackaging.parts.PartName;
- import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
- import org.docx4j.relationships.Relationship;
- import android.util.Log;
- public abstract class BinaryPartAbstractImage extends BinaryPart {
- final static String IMAGE_DIR_PREFIX = "/word/media/";
- final static String IMAGE_NAME_PREFIX = "image";
- public BinaryPartAbstractImage(PartName partName) throws InvalidFormatException {
- super(partName);
- // Can't setContentType or setRelationshipType, since
- // these will differ depending on the nature of the data.
- // Common binary parts should extend this class to
- // provide that information.
- this.getOwningRelationshipPart();
- }
- public BinaryPartAbstractImage(ExternalTarget externalTarget) {
- super(externalTarget);
- }
- // TODO, instead of Part.getOwningRelationshipPart(),
- // it would be better to have getOwningRelationship(),
- // and if required, to get OwningRelationshipPart from that
- // This is a temp workaround
- Relationship rel;
- /**
- * This method assumes your package is a docx (not a pptx or xlsx).
- *
- * @param sourcePart
- * @param proposedRelId
- * @param ext
- * @return
- */
- @Deprecated
- public static String createImageName(Base sourcePart, String proposedRelId, String ext) {
- return PartName.generateUniqueName(sourcePart, proposedRelId,
- IMAGE_DIR_PREFIX, IMAGE_NAME_PREFIX, ext);
- }
- public static String createImageName(OpcPackage opcPackage, Base sourcePart, String proposedRelId, String ext) {
- if (opcPackage instanceof WordprocessingMLPackage) {
- return PartName.generateUniqueName(sourcePart, proposedRelId,
- IMAGE_DIR_PREFIX, IMAGE_NAME_PREFIX, ext);
- } else if (opcPackage instanceof PresentationMLPackage) {
- return PartName.generateUniqueName(sourcePart, proposedRelId,
- "/ppt/media/", IMAGE_NAME_PREFIX, ext);
- } else if (opcPackage instanceof SpreadsheetMLPackage) {
- return PartName.generateUniqueName(sourcePart, proposedRelId,
- "/xl/media/", IMAGE_NAME_PREFIX, ext);
- } else {
- // Shouldn't happen
- return PartName.generateUniqueName(sourcePart, proposedRelId,
- IMAGE_DIR_PREFIX, IMAGE_NAME_PREFIX, ext);
- }
- }
- /**
- * Create an image part from the provided byte array, attach it to the source part
- * (eg the main document part, a header part etc), and return it.
- *
- * Works for both docx and pptx.
- *
- * @param opcPackage
- * @param sourcePart
- * @param bytes
- * @return
- * @throws Exception
- */
- public static BinaryPartAbstractImage createImagePart(
- OpcPackage opcPackage,
- Part sourcePart, byte[] bytes) throws Exception {
- // Whatever image type this is, we're going to need
- // to know its dimensions.
- // For that we use ImageInfo, which can only
- // load an image from a URI.
- // So first, write the bytes to a temp file
- File tmpImageFile = File.createTempFile("img", ".img");
- FileOutputStream fos = new FileOutputStream(tmpImageFile);
- fos.write(bytes);
- fos.close();
- // In the absence of an exception, tmpImageFile now contains an image
- // Word will accept
- ContentTypeManager ctm = opcPackage.getContentTypeManager();
- // Ensure the relationships part exists
- if (sourcePart.getRelationshipsPart() == null) {
- RelationshipsPart.createRelationshipsPartForPart(sourcePart);
- }
- String proposedRelId = sourcePart.getRelationshipsPart().getNextId();
- String ext = "JPG";
- BinaryPartAbstractImage imagePart =
- (BinaryPartAbstractImage) ctm.newPartForContentType(
- ContentTypes.IMAGE_JPEG,
- createImageName(opcPackage, sourcePart, proposedRelId, ext), null);
- FileInputStream fis = new FileInputStream(tmpImageFile);
- imagePart.setBinaryData(fis);
- imagePart.rel = sourcePart.addTargetPart(imagePart, proposedRelId);
- System.gc();
- if (false == tmpImageFile.delete()) {
- Log.e("mcapps debug","Couldn't delete tmp file " + tmpImageFile.getAbsolutePath());
- tmpImageFile.deleteOnExit();
- }
- return imagePart;
- }
- /**
- * Create a <wp:inline> element suitable for this image, which can be
- * linked or embedded in w:p/w:r/w:drawing, specifying height and width. Note
- * that you'd ordinarily use one of the methods which don't require
- * you to specify height (cy).
- *
- * @param filenameHint
- * Any text, for example the original filename
- * @param altText
- * Like HTML's alt text
- * @param id1
- * An id unique in the document
- * @param id2
- * Another id unique in the document None of these things seem to
- * be exposed in Word 2007's user interface, but Word won't open
- * the document if any of the attributes these go in (except @ desc) aren't
- * present!
- * @param cx Image width in EMU
- * @param cy Image height in EMU
- * @param link true if this is to be linked not embedded
- * @throws Exception
- */
- public Inline createImageInline(String filenameHint, String altText,
- /*int id1, int id2,*/ long cx, long cy) throws Exception {
- if (filenameHint == null) {
- filenameHint = "";
- }
- if (altText == null) {
- altText = "";
- }
- cx *= 2 * 2035; //twips
- cy *= 2 * 2035;
- String type = "r:embed";
- String ml =
- // "<w:p ><w:r>" +
- // "<w:drawing>" +
- "<wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"" + namespaces + ">"
- + "<wp:extent cx=\"${cx}\" cy=\"${cy}\"/>"
- + "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>" + //l=\"19050\"
- "<wp:docPr id=\"${id1}\" name=\"${filenameHint}\" descr=\"${altText}\"/><wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/></wp:cNvGraphicFramePr><a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
- + "<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
- + "<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:nvPicPr><pic:cNvPr id=\"${id2}\" name=\"${filenameHint}\"/><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill>"
- + "<a:blip " + type + "=\"${rEmbedId}\"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>"
- + "<pic:spPr><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"${cx}\" cy=\"${cy}\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic>"
- + "</wp:inline>"; // +
- // "</w:drawing>" +
- // "</w:r></w:p>";
- java.util.HashMap<String, String> mappings = new java.util.HashMap<String, String>();
- mappings.put("cx", Long.toString(cx));
- mappings.put("cy", Long.toString(cy));
- mappings.put("filenameHint", filenameHint);
- mappings.put("altText", altText);
- mappings.put("rEmbedId", rel.getId());
- mappings.put("id1", Integer.toString(0)); //id1
- mappings.put("id2", Integer.toString(1)); //id2
- Object o = org.docx4j.XmlUtils.unmarshallFromTemplate(ml, mappings);
- Inline inline = (Inline) ((ae.javax.xml.bind.JAXBElement) o).getValue();
- return inline;
- }
- final static String namespaces = " xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" "
- + "xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" "
- + "xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"";
- public static ImageInfo getImageInfo(URL url) throws Exception {
- // XmlGraphics images caches images by their URI;
- // therefore it can only load images from a URI, rather
- // than say a byte array, byte buffer, or input stream.
- ImageInfo info = new ImageInfo(url.toURI().toString(), ContentTypes.IMAGE_JPEG);
- // Note that these figures do not appear to be reliable for EPS
- // eg ImageMagick 6.2.4 10/02/07 Q16
- // identify fig1.eps
- // reports:
- // fig1.eps PS 516x429 516x429+0+0 DirectClass 869kb
- // whereas ImageInfo reports 1147x953
- /* Note2: odd results for PNG?
- *
- If for an image, ImageMagick (v.6.2.4 and 6.3.7) identify says:
- Resolution: 320x320 (or whatever)
- Units: Undefined <---------------------
- then ImageInfo will report a default value, using Toolkit.getDefaultToolkit().getScreenResolution(),
- which may be say 160.
- To prevent the "Undefined", be sure to use -units when you call convert.
- * When PreloaderImageIO.preloadImage does:
- ImageIOUtil.extractResolution(iiometa, size);
- it is finding the Dimension child, but not "HorizontalPixelSize" or VerticalPixelSize (these are null).
- * */
- return info;
- }
- /**
- * Convenience method, given a Graphic in a document,
- * to get the byte[] representing
- * the associated image
- *
- * @param wmlPkg
- * @param graphic
- * @return
- */
- public static byte[] getImage(WordprocessingMLPackage wmlPkg,
- org.docx4j.dml.Graphic graphic) {
- if (wmlPkg == null
- || wmlPkg.getMainDocumentPart() == null
- || wmlPkg.getMainDocumentPart().getRelationshipsPart() == null) {
- return null;
- }
- Pic pic = graphic.getGraphicData().getPic();
- String rId = pic.getBlipFill().getBlip().getEmbed();
- if (rId.equals("")) {
- rId = pic.getBlipFill().getBlip().getLink();
- }
- log.debug("Image rel id: " + rId);
- org.docx4j.relationships.Relationship rel =
- wmlPkg.getMainDocumentPart().getRelationshipsPart().getRelationshipByID(rId);
- if (rel != null) {
- org.docx4j.openpackaging.parts.Part part =
- wmlPkg.getMainDocumentPart().getRelationshipsPart().getPart(rel);
- if (part == null) {
- log.error("Couldn't get Part!");
- } else if (part instanceof org.docx4j.openpackaging.parts.WordprocessingML.BinaryPart) {
- log.debug("getting bytes...");
- org.docx4j.openpackaging.parts.WordprocessingML.BinaryPart binaryPart =
- (org.docx4j.openpackaging.parts.WordprocessingML.BinaryPart) part;
- java.nio.ByteBuffer bb = binaryPart.getBuffer();
- bb.clear();
- byte[] bytes = new byte[bb.capacity()];
- bb.get(bytes, 0, bytes.length);
- return bytes;
- } else {
- log.error("Part was a " + part.getClass().getName());
- }
- } else {
- log.error("Couldn't find rel " + rId);
- }
- return null;
- }
- // public static class CxCy {
- //
- // long cx;
- //
- // /**
- // * @return the resulting cx
- // */
- // public long getCx() {
- // return cx;
- // }
- // long cy;
- //
- // /**
- // * @return the resulting cy
- // */
- // public long getCy() {
- // return cy;
- // }
- // boolean scaled;
- //
- // /**
- // * @return whether it was necessary to scale
- // * the image to fit the page width
- // */
- // public boolean isScaled() {
- // return scaled;
- // }
- //
- // CxCy(long cx, long cy, boolean scaled) {
- //
- // this.cx = cx;
- // this.cy = cy;
- // this.scaled = scaled;
- //
- // }
- // public static CxCy scale(ImageInfo imageInfo, PageDimensions page) {
- //
- // double writableWidthTwips = page.getWritableWidthTwips();
- // log.debug("writableWidthTwips: " + writableWidthTwips);
- //
- // ImageSize size = imageInfo.getSize();
- //
- // ae.java.awt.geom.Dimension2D dPt = size.getDimensionPt();
- // double imageWidthTwips = dPt.getWidth() * 20;
- // log.debug("imageWidthTwips: " + imageWidthTwips);
- //
- // long cx;
- // long cy;
- // boolean scaled = false;
- // if (imageWidthTwips > writableWidthTwips) {
- //
- // log.debug("Scaling image to fit page width");
- // scaled = true;
- //
- // cx = UnitsOfMeasurement.twipToEMU(writableWidthTwips);
- // cy = UnitsOfMeasurement.twipToEMU(dPt.getHeight() * 20 * writableWidthTwips / imageWidthTwips);
- //
- // } else {
- //
- // log.debug("Scaling image - not necessary");
- //
- // cx = UnitsOfMeasurement.twipToEMU(imageWidthTwips);
- // cy = UnitsOfMeasurement.twipToEMU(dPt.getHeight() * 20);
- // }
- //
- // return new CxCy(cx, cy, scaled);
- // }
- // }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement