Changeset 1679
- Timestamp:
- 10/07/11 00:09:49 (8 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/docx4j/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/BinaryPartAbstractImage.java
r1559 r1679 18 18 19 19 */ 20 21 20 package org.docx4j.openpackaging.parts.WordprocessingML; 22 21 … … 67 66 import org.docx4j.wml.SectPr.PgSz; 68 67 69 70 68 public abstract class BinaryPartAbstractImage extends BinaryPart { 71 69 72 70 protected static Logger log = Logger.getLogger(BinaryPartAbstractImage.class); 73 74 71 final static String IMAGE_DIR_PREFIX = "/word/media/"; 75 72 final static String IMAGE_NAME_PREFIX = "image"; … … 90 87 super(externalTarget); 91 88 } 92 93 94 89 ImageInfo imageInfo; 95 90 96 91 public ImageInfo getImageInfo() { 97 92 98 if (imageInfo==null) { 99 93 if (imageInfo == null) { 100 94 // TODO - create it 101 102 95 // Save byte buffer as a tmp file 103 104 96 // Generate ImageInfo 105 106 97 // Delete tmp file 107 108 98 } 109 99 … … 114 104 this.imageInfo = imageInfo; 115 105 } 116 117 106 // TODO, instead of Part.getOwningRelationshipPart(), 118 107 // it would be better to have getOwningRelationship(), … … 120 109 // This is a temp workaround 121 110 Relationship rel; 122 123 111 static int density = 150; 112 124 113 /** 125 114 * Set the resolution at which a PDF or EPS is converted … … 139 128 140 129 } 141 142 130 static ImageManager imageManager; 143 131 … … 160 148 } 161 149 150 /* 151 * Possibility to put directly an image filePath instead of giving an image byte array 152 * @param wordMLPackage 153 * @param filePath 154 * 155 */ 156 public static BinaryPartAbstractImage createImagePart(WordprocessingMLPackage wordMLPackage, 157 String filePath) throws Exception { 158 159 return createImagePartFromFilePath(wordMLPackage, 160 wordMLPackage.getMainDocumentPart(), filePath); 161 162 } 163 162 164 /** 163 165 * This method assumes your package is a docx (not a pptx or xlsx). … … 169 171 */ 170 172 @Deprecated 171 public static String createImageName(Base sourcePart, String proposedRelId, String ext) {173 public static String createImageName(Base sourcePart, String proposedRelId, String ext) { 172 174 173 175 return PartName.generateUniqueName(sourcePart, proposedRelId, … … 175 177 } 176 178 177 public static String createImageName(OpcPackage opcPackage, Base sourcePart, String proposedRelId, String ext) {179 public static String createImageName(OpcPackage opcPackage, Base sourcePart, String proposedRelId, String ext) { 178 180 179 181 if (opcPackage instanceof WordprocessingMLPackage) { … … 193 195 } 194 196 195 196 197 197 /** 198 198 * Create an image part from the provided byte array, attach it to the source part … … 222 222 fos.write(bytes); 223 223 fos.close(); 224 log.debug("created tmp file: " + tmpImageFile.getAbsolutePath());224 log.debug("created tmp file: " + tmpImageFile.getAbsolutePath()); 225 225 226 226 ImageInfo info = ensureFormatIsSupported(tmpImageFile.getAbsolutePath(), tmpImageFile, bytes); … … 232 232 233 233 // Ensure the relationships part exists 234 if (sourcePart.getRelationshipsPart()==null) 234 if (sourcePart.getRelationshipsPart() == null) { 235 235 RelationshipsPart.createRelationshipsPartForPart(sourcePart); 236 } 236 237 237 238 String proposedRelId = sourcePart.getRelationshipsPart().getNextId(); 238 239 239 String ext = info.getMimeType().substring( info.getMimeType().indexOf("/")+1);240 String ext = info.getMimeType().substring(info.getMimeType().indexOf("/") + 1); 240 241 241 242 // System.out.println(ext); 242 243 243 244 BinaryPartAbstractImage imagePart = 244 (BinaryPartAbstractImage)ctm.newPartForContentType(245 (BinaryPartAbstractImage) ctm.newPartForContentType( 245 246 info.getMimeType(), 246 createImageName(opcPackage, sourcePart, proposedRelId, ext), null 247 ); 248 249 log.debug("created part " + imagePart.getClass().getName() + 250 " with name " + imagePart.getPartName().toString() ); 247 createImageName(opcPackage, sourcePart, proposedRelId, ext), null); 248 249 log.debug("created part " + imagePart.getClass().getName() 250 + " with name " + imagePart.getPartName().toString()); 251 251 252 252 FileInputStream fis = new FileInputStream(tmpImageFile); 253 imagePart.setBinaryData( fis);254 255 imagePart.rel =sourcePart.addTargetPart(imagePart, proposedRelId);253 imagePart.setBinaryData(fis); 254 255 imagePart.rel = sourcePart.addTargetPart(imagePart, proposedRelId); 256 256 257 257 imagePart.setImageInfo(info); … … 264 264 fis = null; 265 265 System.gc(); 266 if (tmpImageFile.delete()) {267 log.debug(".. deleted " + tmpImageFile.getAbsolutePath() ); 266 if (tmpImageFile.delete()) { 267 log.debug(".. deleted " + tmpImageFile.getAbsolutePath()); 268 268 } else { 269 269 log.warn("Couldn't delete tmp file " + tmpImageFile.getAbsolutePath()); … … 277 277 } 278 278 279 /** 279 /* 280 * Default, we suppose that image is load in a Byte Array (using function createImagePart) so isLoad is true. 281 * If we use createImagePartFromFilePath, then isLoad is false 282 */ 283 static boolean isLoad = true; 284 285 /** 286 * Create an image part from the provided filePath image, attach it to the source part 287 * (eg the main document part, a header part etc), and return it. 288 * 289 * Works for both docx and pptx. 290 * 291 * @param opcPackage 292 * @param sourcePart 293 * @param filePath 294 * @return 295 * @throws Exception 296 */ 297 public static BinaryPartAbstractImage createImagePartFromFilePath( 298 OpcPackage opcPackage, 299 Part sourcePart, String filePath) throws Exception { 300 301 final File locFile = new File(filePath); 302 final byte[] locByte = new byte[1]; 303 //We are in the case that image is not load (no byte Array) so isLoad is false 304 isLoad = false; 305 //Here, filePath doesn't represent the tmpFile but the path of the image to load 306 ImageInfo info = ensureFormatIsSupported(filePath, locFile, locByte); 307 308 ContentTypeManager ctm = opcPackage.getContentTypeManager(); 309 310 // Ensure the relationships part exists 311 if (sourcePart.getRelationshipsPart() == null) { 312 RelationshipsPart.createRelationshipsPartForPart(sourcePart); 313 } 314 315 String proposedRelId = sourcePart.getRelationshipsPart().getNextId(); 316 317 String ext = info.getMimeType().substring(info.getMimeType().indexOf("/") + 1); 318 319 BinaryPartAbstractImage imagePart = 320 (BinaryPartAbstractImage) ctm.newPartForContentType( 321 info.getMimeType(), 322 createImageName(opcPackage, sourcePart, proposedRelId, ext), null); 323 324 log.debug("created part " + imagePart.getClass().getName() 325 + " with name " + imagePart.getPartName().toString()); 326 327 FileInputStream fis = new FileInputStream(locFile); 328 imagePart.setBinaryData(fis); 329 330 imagePart.rel = sourcePart.addTargetPart(imagePart, proposedRelId); 331 332 imagePart.setImageInfo(info); 333 334 return imagePart; 335 336 } 337 338 /** 280 339 * @param bytes 281 340 * @param imageFile … … 306 365 // (To use an image natively, we do need a preloader) 307 366 imagePreloaderFound = false; 308 log.warn(e.getMessage());367 log.warn(e.getMessage()); 309 368 } 310 369 311 if ( imagePreloaderFound && 312 (info.getMimeType().equals(ContentTypes.IMAGE_TIFF)370 if (imagePreloaderFound 371 && (info.getMimeType().equals(ContentTypes.IMAGE_TIFF) 313 372 || info.getMimeType().equals(ContentTypes.IMAGE_EMF2) // ImageInfo 314 373 || info.getMimeType().equals(ContentTypes.IMAGE_WMF) … … 317 376 || info.getMimeType().equals(ContentTypes.IMAGE_GIF) 318 377 // || info.getMimeType().equals(ContentTypes.IMAGE_EPS) 319 || info.getMimeType().equals(ContentTypes.IMAGE_BMP) 320 )) { 378 || info.getMimeType().equals(ContentTypes.IMAGE_BMP))) { 321 379 // TODO: add other supported formats 322 380 … … 325 383 log.debug(".. supported natively by Word"); 326 384 327 } else if ( imageFile!=null && bytes!=null) {385 } else if (imageFile != null && bytes != null) { 328 386 329 387 // otherwise (eg if its an EPS or PDF), try to convert it … … 337 395 log.debug(".. attempting to convert to PNG"); 338 396 339 ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 340 fos = new FileOutputStream(imageFile); 341 342 convertToPNG(bais, fos, density); 397 //If image haven't been load (using function createImagePartFromFilePath), we load it 398 if (isLoad == false) { 399 400 // So first, we create tmpFile 401 File tmpImageFile = File.createTempFile("img", ".img"); 402 fos = new FileOutputStream(tmpImageFile); 403 404 //Now we get the inputStream, which is represented by imageFile in this case 405 FileInputStream bais = new FileInputStream(imageFile); 406 407 //We convert 408 convertToPNG(bais, fos, density); 409 410 //We don't forget to change locFile because the new image file is the converted image file!! 411 imageFile = tmpImageFile; 412 413 } //Else image has been load in an array (using function cretaImagePart) 414 else { 415 ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 416 fos = new FileOutputStream(imageFile); 417 convertToPNG(bais, fos, density); 418 } 419 343 420 fos.close(); 344 421 fos = null; … … 346 423 // We need to refresh image info 347 424 imageManager.getCache().clearCache(); 348 info = getImageInfo(imageFile.getAbsolutePath());425 info = getImageInfo(imageFile.getAbsolutePath()); 349 426 350 427 // Debug ... … … 359 436 } 360 437 361 362 438 /** 363 439 * Create a linked image part, and attach it as a rel of the docx main document part … … 387 463 Part sourcePart, String fileurl) throws Exception { 388 464 389 ImageInfo info = ensureFormatIsSupported(fileurl, null,null);465 ImageInfo info = ensureFormatIsSupported(fileurl, null, null); 390 466 391 467 ContentTypeManager ctm = opcPackage.getContentTypeManager(); … … 393 469 // In order to ensure unique part name, 394 470 // idea is to use the relId, which ought to be unique 395 String ext = info.getMimeType().substring( info.getMimeType().indexOf("/")+1);471 String ext = info.getMimeType().substring(info.getMimeType().indexOf("/") + 1); 396 472 397 473 BinaryPartAbstractImage imagePart = 398 (BinaryPartAbstractImage)ctm.newPartForContentType(474 (BinaryPartAbstractImage) ctm.newPartForContentType( 399 475 info.getMimeType(), 400 createImageName(opcPackage, sourcePart, proposedRelId, ext ), null);476 createImageName(opcPackage, sourcePart, proposedRelId, ext), null); 401 477 402 478 log.debug("created part " + imagePart.getClass().getName() … … 419 495 } 420 496 421 422 497 /** 423 498 * Create a <wp:inline> element suitable for this image, … … 439 514 int id1, int id2) throws Exception { 440 515 441 return createImageInline( filenameHint, altText, 442 id1,id2, false);516 return createImageInline(filenameHint, altText, 517 id1, id2, false); 443 518 444 519 } … … 462 537 int id1, int id2, boolean link) throws Exception { 463 538 464 WordprocessingMLPackage wmlPackage = ((WordprocessingMLPackage)this.getPackage());539 WordprocessingMLPackage wmlPackage = ((WordprocessingMLPackage) this.getPackage()); 465 540 466 541 List<SectionWrapper> sections = wmlPackage.getDocumentModel().getSections(); 467 PageDimensions page = sections.get(sections.size()-1).getPageDimensions();542 PageDimensions page = sections.get(sections.size() - 1).getPageDimensions(); 468 543 469 544 CxCy cxcy = CxCy.scale(imageInfo, page); 470 545 471 return createImageInline( filenameHint, altText, 472 id1, id2, cxcy.getCx(), cxcy.getCy(), link ); 473 } 474 546 return createImageInline(filenameHint, altText, 547 id1, id2, cxcy.getCx(), cxcy.getCy(), link); 548 } 475 549 476 550 /** … … 492 566 int id1, int id2, long cx) throws Exception { 493 567 494 return createImageInline( filenameHint, altText, 495 id1,id2, cx, false);568 return createImageInline(filenameHint, altText, 569 id1, id2, cx, false); 496 570 497 571 } … … 559 633 int id1, int id2, long cx, long cy, boolean link) throws Exception { 560 634 561 if (filenameHint==null) {635 if (filenameHint == null) { 562 636 filenameHint = ""; 563 637 } 564 if (altText==null) {638 if (altText == null) { 565 639 altText = ""; 566 640 } … … 576 650 // "<w:p ><w:r>" + 577 651 // "<w:drawing>" + 578 "<wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"" + namespaces + ">" +579 "<wp:extent cx=\"${cx}\" cy=\"${cy}\"/>" +580 "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>" +//l=\"19050\"581 "<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\">" +582 "<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +583 "<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>" +584 "<a:blip " + type +"=\"${rEmbedId}\"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>" +585 "<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>" +586 "</wp:inline>"; // +652 "<wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"" + namespaces + ">" 653 + "<wp:extent cx=\"${cx}\" cy=\"${cy}\"/>" 654 + "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>" + //l=\"19050\" 655 "<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\">" 656 + "<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" 657 + "<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>" 658 + "<a:blip " + type + "=\"${rEmbedId}\"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>" 659 + "<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>" 660 + "</wp:inline>"; // + 587 661 // "</w:drawing>" + 588 662 // "</w:r></w:p>"; 589 java.util.HashMap<String, String> mappings = new java.util.HashMap<String, String>();663 java.util.HashMap<String, String> mappings = new java.util.HashMap<String, String>(); 590 664 591 665 mappings.put("cx", Long.toString(cx)); … … 593 667 mappings.put("filenameHint", filenameHint); 594 668 mappings.put("altText", altText); 595 mappings.put("rEmbedId", rel.getId() );669 mappings.put("rEmbedId", rel.getId()); 596 670 mappings.put("id1", Integer.toString(id1)); 597 671 mappings.put("id2", Integer.toString(id2)); 598 672 599 Object o = org.docx4j.XmlUtils.unmarshallFromTemplate(ml, mappings ) ;600 Inline inline = (Inline) ((JAXBElement)o).getValue();673 Object o = org.docx4j.XmlUtils.unmarshallFromTemplate(ml, mappings); 674 Inline inline = (Inline) ((JAXBElement) o).getValue(); 601 675 602 676 return inline; 603 677 } 604 605 final static String namespaces = " xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" " + 606 "xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" " + 607 "xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\""; 608 678 final static String namespaces = " xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" " 679 + "xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" " 680 + "xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\""; 609 681 610 682 public static ImageInfo getImageInfo(String uri) throws Exception { … … 662 734 } 663 735 664 665 public static void displayImageInfo(ImageInfo info ) { 666 736 public static void displayImageInfo(ImageInfo info) { 737 667 738 ImageSize size = info.getSize(); 668 739 … … 671 742 672 743 log.debug(info.getOriginalURI() + " " + info.getMimeType() 673 + " " + Math.round(dPx.getWidth()) +"x" + Math.round(dPx.getHeight()));744 + " " + Math.round(dPx.getWidth()) + "x" + Math.round(dPx.getHeight())); 674 745 675 log.debug("Resolution:" + Math.round(size.getDpiHorizontal()) + "x" + Math.round(size.getDpiVertical()));676 log.debug("Print size: " + Math.round(dPt.getWidth()/72) + "\" x" + Math.round(dPt.getHeight()/72)+"\"" ); 746 log.debug("Resolution:" + Math.round(size.getDpiHorizontal()) + "x" + Math.round(size.getDpiVertical())); 747 log.debug("Print size: " + Math.round(dPt.getWidth() / 72) + "\" x" + Math.round(dPt.getHeight() / 72) + "\""); 677 748 678 749 } … … 720 791 return bytes; 721 792 } else { 722 log.error("Part was a " + part.getClass().getName());793 log.error("Part was a " + part.getClass().getName()); 723 794 } 724 795 } else { … … 732 803 733 804 long cx; 805 734 806 /** 735 807 * @return the resulting cx … … 738 810 return cx; 739 811 } 740 741 812 long cy; 813 742 814 /** 743 815 * @return the resulting cy … … 747 819 } 748 820 boolean scaled; 821 749 822 /** 750 823 * @return whether it was necessary to scale … … 777 850 long cy; 778 851 boolean scaled = false; 779 if (imageWidthTwips>writableWidthTwips) {852 if (imageWidthTwips > writableWidthTwips) { 780 853 781 854 log.debug("Scaling image to fit page width"); … … 783 856 784 857 cx = UnitsOfMeasurement.twipToEMU(writableWidthTwips); 785 cy = UnitsOfMeasurement.twipToEMU(dPt.getHeight() * 20 * writableWidthTwips/imageWidthTwips);858 cy = UnitsOfMeasurement.twipToEMU(dPt.getHeight() * 20 * writableWidthTwips / imageWidthTwips); 786 859 787 860 } else { … … 800 873 801 874 } 802 803 875 } 804 876 … … 814 886 * @throws InterruptedException 815 887 */ 816 public static void convertToPNG(InputStream is, OutputStream os, int density) throws IOException, InterruptedException{888 public static void convertToPNG(InputStream is, OutputStream os, int density) throws IOException, InterruptedException { 817 889 818 890 /* … … 863 935 } 864 936 865 if (p.waitFor()!=0) {937 if (p.waitFor() != 0) { 866 938 log.error("Error"); 867 939 } … … 873 945 while (true) { 874 946 int bytesRead = is.read(buffer); 875 if ( bytesRead == -1 ) break; 947 if (bytesRead == -1) { 948 break; 949 } 876 950 os.write(buffer, 0, bytesRead); 877 951 } … … 880 954 }//class 881 955 882 883 class StreamGobbler extends Thread 884 { 956 class StreamGobbler extends Thread { 885 957 // The term "StreamGobbler" was taken from an article called "When Runtime.exec() won't", 886 958 // see http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html. … … 889 961 OutputStream os; 890 962 891 892 StreamGobbler(InputStream is, OutputStream redirect) 893 { 894 this.is = new BufferedInputStream(is); 963 StreamGobbler(InputStream is, OutputStream redirect) { 964 this.is = new BufferedInputStream(is); 895 965 this.os = redirect; 896 966 } 897 967 898 public void run() 899 { 900 try 901 { 968 public void run() { 969 try { 902 970 BinaryPartAbstractImage.copy2(is, os); 903 } catch (IOException ioe) 904 { 971 } catch (IOException ioe) { 905 972 ioe.printStackTrace(); 906 973 } 907 974 } 908 909 } 910 975 }
Note: See TracChangeset
for help on using the changeset viewer.
