Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

XSLFPictureData.java 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * ====================================================================
  3. * Licensed to the Apache Software Foundation (ASF) under one or more
  4. * contributor license agreements. See the NOTICE file distributed with
  5. * this work for additional information regarding copyright ownership.
  6. * The ASF licenses this file to You under the Apache License, Version 2.0
  7. * (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. * ====================================================================
  18. */
  19. package org.apache.poi.xslf.usermodel;
  20. import java.awt.Dimension;
  21. import java.io.IOException;
  22. import java.io.InputStream;
  23. import java.io.OutputStream;
  24. import org.apache.poi.ooxml.POIXMLDocumentPart;
  25. import org.apache.poi.ooxml.POIXMLException;
  26. import org.apache.poi.openxml4j.opc.PackagePart;
  27. import org.apache.poi.sl.image.ImageHeaderBitmap;
  28. import org.apache.poi.sl.image.ImageHeaderEMF;
  29. import org.apache.poi.sl.image.ImageHeaderPICT;
  30. import org.apache.poi.sl.image.ImageHeaderWMF;
  31. import org.apache.poi.sl.usermodel.PictureData;
  32. import org.apache.poi.util.Beta;
  33. import org.apache.poi.util.IOUtils;
  34. import org.apache.poi.util.LittleEndian;
  35. import org.apache.poi.util.LittleEndianConsts;
  36. import org.apache.poi.util.Units;
  37. /**
  38. * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type
  39. */
  40. @Beta
  41. public final class XSLFPictureData extends POIXMLDocumentPart implements PictureData {
  42. private static final int DEFAULT_MAX_IMAGE_SIZE = 100_000_000;
  43. private static int MAX_IMAGE_SIZE = DEFAULT_MAX_IMAGE_SIZE;
  44. /**
  45. * @param length the max image size allowed for XSLF pictures
  46. */
  47. public static void setMaxImageSize(int length) {
  48. MAX_IMAGE_SIZE = length;
  49. }
  50. /**
  51. * @return the max image size allowed for XSLF pictures
  52. */
  53. public static int getMaxImageSize() {
  54. return MAX_IMAGE_SIZE;
  55. }
  56. private Long checksum;
  57. // original image dimensions (for formats supported by BufferedImage)
  58. private Dimension origSize;
  59. private int index = -1;
  60. /**
  61. * Create a new XSLFGraphicData node
  62. */
  63. protected XSLFPictureData() {
  64. super();
  65. }
  66. /**
  67. * Construct XSLFPictureData from a package part
  68. *
  69. * @param part the package part holding the drawing data
  70. *
  71. * @since POI 3.14-Beta1
  72. */
  73. public XSLFPictureData(PackagePart part) {
  74. super(part);
  75. }
  76. /**
  77. * An InputStream to read the picture data directly
  78. * from the underlying package part
  79. *
  80. * @return InputStream
  81. */
  82. public InputStream getInputStream() throws IOException {
  83. return getPackagePart().getInputStream();
  84. }
  85. /**
  86. * Gets the picture data as a byte array.
  87. *
  88. * You can grab the picture data directly from the underlying package part with the {@link #getInputStream()} method
  89. *
  90. * @return the Picture data.
  91. */
  92. public byte[] getData() {
  93. try (InputStream stream = getInputStream()) {
  94. return IOUtils.toByteArrayWithMaxLength(stream, getMaxImageSize());
  95. } catch (IOException e) {
  96. throw new POIXMLException(e);
  97. }
  98. }
  99. /**
  100. * Returns the file name of the image, eg image7.jpg . The original filename
  101. * isn't always available, but if it can be found it's likely to be in the
  102. * CTDrawing
  103. */
  104. public String getFileName() {
  105. String name = getPackagePart().getPartName().getName();
  106. return name.substring(name.lastIndexOf('/') + 1);
  107. }
  108. /**
  109. * Suggests a file extension for this image.
  110. *
  111. * @return the file extension.
  112. */
  113. public String suggestFileExtension() {
  114. return getPackagePart().getPartName().getExtension();
  115. }
  116. @Override
  117. public byte[] getChecksum() {
  118. cacheProperties();
  119. byte[] cs = new byte[LittleEndianConsts.LONG_SIZE];
  120. LittleEndian.putLong(cs,0,checksum);
  121. return cs;
  122. }
  123. @Override
  124. public Dimension getImageDimension() {
  125. cacheProperties();
  126. return origSize;
  127. }
  128. @Override
  129. public Dimension getImageDimensionInPixels() {
  130. Dimension dim = getImageDimension();
  131. return new Dimension(
  132. Units.pointsToPixel(dim.getWidth()),
  133. Units.pointsToPixel(dim.getHeight())
  134. );
  135. }
  136. /**
  137. * Determine and cache image properties
  138. */
  139. protected void cacheProperties() {
  140. if (origSize == null || checksum == null) {
  141. byte[] data = getData();
  142. checksum = IOUtils.calculateChecksum(data);
  143. PictureType pt = getType();
  144. if (pt == null) {
  145. origSize = new Dimension(1,1);
  146. return;
  147. }
  148. switch (pt) {
  149. case EMF:
  150. origSize = new ImageHeaderEMF(data, 0).getSize();
  151. break;
  152. case WMF:
  153. // wmf files in pptx usually have their placeable header
  154. // stripped away, so this returns only the dummy size
  155. origSize = new ImageHeaderWMF(data, 0).getSize();
  156. break;
  157. case PICT:
  158. origSize = new ImageHeaderPICT(data, 0).getSize();
  159. break;
  160. default:
  161. origSize = new ImageHeaderBitmap(data, 0).getSize();
  162. break;
  163. }
  164. }
  165. }
  166. /**
  167. * *PictureData objects store the actual content in the part directly without keeping a
  168. * copy like all others therefore we need to handle them differently.
  169. */
  170. @Override
  171. protected void prepareForCommit() {
  172. // do not clear the part here
  173. }
  174. @Override
  175. public String getContentType() {
  176. return getPackagePart().getContentType();
  177. }
  178. public void setData(byte[] data) throws IOException {
  179. try (OutputStream os = getPackagePart().getOutputStream()) {
  180. os.write(data);
  181. }
  182. // recalculate now since we already have the data bytes available anyhow
  183. checksum = IOUtils.calculateChecksum(data);
  184. origSize = null; // need to recalculate image size
  185. }
  186. @Override
  187. public PictureType getType() {
  188. String ct = getContentType();
  189. if (XSLFRelation.IMAGE_EMF.getContentType().equals(ct)) {
  190. return PictureType.EMF;
  191. } else if (XSLFRelation.IMAGE_WMF.getContentType().equals(ct)) {
  192. return PictureType.WMF;
  193. } else if (XSLFRelation.IMAGE_PICT.getContentType().equals(ct)) {
  194. return PictureType.PICT;
  195. } else if (XSLFRelation.IMAGE_JPEG.getContentType().equals(ct)) {
  196. return PictureType.JPEG;
  197. } else if (XSLFRelation.IMAGE_PNG.getContentType().equals(ct)) {
  198. return PictureType.PNG;
  199. } else if (XSLFRelation.IMAGE_DIB.getContentType().equals(ct)) {
  200. return PictureType.DIB;
  201. } else if (XSLFRelation.IMAGE_GIF.getContentType().equals(ct)) {
  202. return PictureType.GIF;
  203. } else if (XSLFRelation.IMAGE_EPS.getContentType().equals(ct)) {
  204. return PictureType.EPS;
  205. } else if (XSLFRelation.IMAGE_BMP.getContentType().equals(ct)) {
  206. return PictureType.BMP;
  207. } else if (XSLFRelation.IMAGE_WPG.getContentType().equals(ct)) {
  208. return PictureType.WPG;
  209. } else if (XSLFRelation.IMAGE_WDP.getContentType().equals(ct)) {
  210. return PictureType.WDP;
  211. } else if (XSLFRelation.IMAGE_TIFF.getContentType().equals(ct)) {
  212. return PictureType.TIFF;
  213. } else if (XSLFRelation.IMAGE_SVG.getContentType().equals(ct)) {
  214. return PictureType.SVG;
  215. } else {
  216. return null;
  217. }
  218. }
  219. /* package */ static XSLFRelation getRelationForType(PictureType pt) {
  220. switch (pt) {
  221. case EMF: return XSLFRelation.IMAGE_EMF;
  222. case WMF: return XSLFRelation.IMAGE_WMF;
  223. case PICT: return XSLFRelation.IMAGE_PICT;
  224. case JPEG: return XSLFRelation.IMAGE_JPEG;
  225. case PNG: return XSLFRelation.IMAGE_PNG;
  226. case DIB: return XSLFRelation.IMAGE_DIB;
  227. case GIF: return XSLFRelation.IMAGE_GIF;
  228. case EPS: return XSLFRelation.IMAGE_EPS;
  229. case BMP: return XSLFRelation.IMAGE_BMP;
  230. case WPG: return XSLFRelation.IMAGE_WPG;
  231. case WDP: return XSLFRelation.IMAGE_WDP;
  232. case TIFF: return XSLFRelation.IMAGE_TIFF;
  233. case SVG: return XSLFRelation.IMAGE_SVG;
  234. default: return null;
  235. }
  236. }
  237. /**
  238. * @return the 0-based index of this pictures within the picture parts
  239. */
  240. public int getIndex() {
  241. return index;
  242. }
  243. /**
  244. * @param index sets the 0-based index of this pictures within the picture parts
  245. */
  246. public void setIndex(int index) {
  247. this.index = index;
  248. }
  249. }