| 1 50 51 package com.lowagie.text; 52 53 import java.awt.Graphics2D ; 54 import java.awt.color.ICC_Profile ; 55 import java.awt.image.BufferedImage ; 56 import java.io.IOException ; 57 import java.io.InputStream ; 58 import java.lang.reflect.Constructor ; 59 import java.net.MalformedURLException ; 60 import java.net.URL ; 61 import java.util.ArrayList ; 62 63 import com.lowagie.text.pdf.PRIndirectReference; 64 import com.lowagie.text.pdf.PdfArray; 65 import com.lowagie.text.pdf.PdfContentByte; 66 import com.lowagie.text.pdf.PdfDictionary; 67 import com.lowagie.text.pdf.PdfIndirectReference; 68 import com.lowagie.text.pdf.PdfName; 69 import com.lowagie.text.pdf.PdfNumber; 70 import com.lowagie.text.pdf.PdfOCG; 71 import com.lowagie.text.pdf.PdfObject; 72 import com.lowagie.text.pdf.PdfReader; 73 import com.lowagie.text.pdf.PdfTemplate; 74 import com.lowagie.text.pdf.PdfWriter; 75 import com.lowagie.text.pdf.RandomAccessFileOrArray; 76 import com.lowagie.text.pdf.codec.BmpImage; 77 import com.lowagie.text.pdf.codec.CCITTG4Encoder; 78 import com.lowagie.text.pdf.codec.GifImage; 79 import com.lowagie.text.pdf.codec.PngImage; 80 import com.lowagie.text.pdf.codec.TiffImage; 81 82 89 90 public abstract class Image extends Rectangle { 91 92 94 95 public static final int DEFAULT = 0; 96 97 98 public static final int RIGHT = 2; 99 100 101 public static final int LEFT = 0; 102 103 104 public static final int MIDDLE = 1; 105 106 107 public static final int TEXTWRAP = 4; 108 109 110 public static final int UNDERLYING = 8; 111 112 113 public static final int AX = 0; 114 115 116 public static final int AY = 1; 117 118 119 public static final int BX = 2; 120 121 122 public static final int BY = 3; 123 124 125 public static final int CX = 4; 126 127 128 public static final int CY = 5; 129 130 131 public static final int DX = 6; 132 133 134 public static final int DY = 7; 135 136 137 public static final int ORIGINAL_NONE = 0; 138 139 140 public static final int ORIGINAL_JPEG = 1; 141 142 143 public static final int ORIGINAL_PNG = 2; 144 145 146 public static final int ORIGINAL_GIF = 3; 147 148 149 public static final int ORIGINAL_BMP = 4; 150 151 152 public static final int ORIGINAL_TIFF = 5; 153 154 155 public static final int ORIGINAL_WMF = 6; 156 157 158 public static final int ORIGINAL_PS = 7; 159 160 162 163 protected int type; 164 165 166 protected URL url; 167 168 169 protected byte rawData[]; 170 171 172 protected int bpc = 1; 173 174 175 protected PdfTemplate template[] = new PdfTemplate[1]; 176 177 178 protected int alignment; 179 180 181 protected String alt; 182 183 184 protected float absoluteX = Float.NaN; 185 186 187 protected float absoluteY = Float.NaN; 188 189 190 protected float plainWidth; 191 192 193 protected float plainHeight; 194 195 196 protected float scaledWidth; 197 198 199 protected float scaledHeight; 200 201 202 protected Long mySerialId = getSerialId(); 203 204 206 212 public Image(URL url) { 213 super(0, 0); 214 this.url = url; 215 this.alignment = DEFAULT; 216 rotationRadians = 0; 217 } 218 219 229 public static Image getInstance(URL url) throws BadElementException, 230 MalformedURLException , IOException { 231 InputStream is = null; 232 try { 233 is = url.openStream(); 234 int c1 = is.read(); 235 int c2 = is.read(); 236 int c3 = is.read(); 237 int c4 = is.read(); 238 is.close(); 239 240 is = null; 241 if (c1 == 'G' && c2 == 'I' && c3 == 'F') { 242 GifImage gif = new GifImage(url); 243 Image img = gif.getImage(1); 244 return img; 245 } 246 if (c1 == 0xFF && c2 == 0xD8) { 247 return new Jpeg(url); 248 } 249 if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1] 250 && c3 == PngImage.PNGID[2] && c4 == PngImage.PNGID[3]) { 251 return PngImage.getImage(url); 252 } 253 if (c1 == 0xD7 && c2 == 0xCD) { 254 return new ImgWMF(url); 255 } 256 if (c1 == 'B' && c2 == 'M') { 257 return BmpImage.getImage(url); 258 } 259 if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42) 260 || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { 261 RandomAccessFileOrArray ra = null; 262 try { 263 if (url.getProtocol().equals("file")) { 264 String file = url.getFile(); 265 file = Utilities.unEscapeURL(file); 266 ra = new RandomAccessFileOrArray(file); 267 } else 268 ra = new RandomAccessFileOrArray(url); 269 Image img = TiffImage.getTiffImage(ra, 1); 270 img.url = url; 271 return img; 272 } finally { 273 if (ra != null) 274 ra.close(); 275 } 276 277 } 278 throw new IOException (url.toString() 279 + " is not a recognized imageformat."); 280 } finally { 281 if (is != null) { 282 is.close(); 283 } 284 } 285 } 286 287 298 public static Image getInstance(String filename) 299 throws BadElementException, MalformedURLException , IOException { 300 return getInstance(Utilities.toURL(filename)); 301 } 302 303 313 public static Image getInstance(byte imgb[]) throws BadElementException, 314 MalformedURLException , IOException { 315 InputStream is = null; 316 try { 317 is = new java.io.ByteArrayInputStream (imgb); 318 int c1 = is.read(); 319 int c2 = is.read(); 320 int c3 = is.read(); 321 int c4 = is.read(); 322 is.close(); 323 324 is = null; 325 if (c1 == 'G' && c2 == 'I' && c3 == 'F') { 326 GifImage gif = new GifImage(imgb); 327 return gif.getImage(1); 328 } 329 if (c1 == 0xFF && c2 == 0xD8) { 330 return new Jpeg(imgb); 331 } 332 if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1] 333 && c3 == PngImage.PNGID[2] && c4 == PngImage.PNGID[3]) { 334 return PngImage.getImage(imgb); 335 } 336 if (c1 == 0xD7 && c2 == 0xCD) { 337 return new ImgWMF(imgb); 338 } 339 if (c1 == 'B' && c2 == 'M') { 340 return BmpImage.getImage(imgb); 341 } 342 if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42) 343 || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { 344 RandomAccessFileOrArray ra = null; 345 try { 346 ra = new RandomAccessFileOrArray(imgb); 347 Image img = TiffImage.getTiffImage(ra, 1); 348 if (img.getOriginalData() == null) 349 img.setOriginalData(imgb); 350 return img; 351 } finally { 352 if (ra != null) 353 ra.close(); 354 } 355 356 } 357 throw new IOException ( 358 "The byte array is not a recognized imageformat."); 359 } finally { 360 if (is != null) { 361 is.close(); 362 } 363 } 364 } 365 366 383 public static Image getInstance(int width, int height, int components, 384 int bpc, byte data[]) throws BadElementException { 385 return Image.getInstance(width, height, components, bpc, data, null); 386 } 387 388 412 public static Image getInstance(int width, int height, boolean reverseBits, 413 int typeCCITT, int parameters, byte[] data) 414 throws BadElementException { 415 return Image.getInstance(width, height, reverseBits, typeCCITT, 416 parameters, data, null); 417 } 418 419 446 public static Image getInstance(int width, int height, boolean reverseBits, 447 int typeCCITT, int parameters, byte[] data, int transparency[]) 448 throws BadElementException { 449 if (transparency != null && transparency.length != 2) 450 throw new BadElementException( 451 "Transparency length must be equal to 2 with CCITT images"); 452 Image img = new ImgCCITT(width, height, reverseBits, typeCCITT, 453 parameters, data); 454 img.transparency = transparency; 455 return img; 456 } 457 458 478 public static Image getInstance(int width, int height, int components, 479 int bpc, byte data[], int transparency[]) 480 throws BadElementException { 481 if (transparency != null && transparency.length != components * 2) 482 throw new BadElementException( 483 "Transparency length must be equal to (componentes * 2)"); 484 if (components == 1 && bpc == 1) { 485 byte g4[] = CCITTG4Encoder.compress(data, width, height); 486 return Image.getInstance(width, height, false, Image.CCITTG4, 487 Image.CCITT_BLACKIS1, g4, transparency); 488 } 489 Image img = new ImgRaw(width, height, components, bpc, data); 490 img.transparency = transparency; 491 return img; 492 } 493 494 496 504 public static Image getInstance(PdfTemplate template) 505 throws BadElementException { 506 return new ImgTemplate(template); 507 } 508 509 511 527 public static Image getInstance(java.awt.Image image, java.awt.Color color, 528 boolean forceBW) throws BadElementException, IOException { 529 530 if(image instanceof BufferedImage ){ 531 BufferedImage bi = (BufferedImage ) image; 532 if(bi.getType()==BufferedImage.TYPE_BYTE_BINARY) { 533 forceBW=true; 534 } 535 } 536 537 java.awt.image.PixelGrabber pg = new java.awt.image.PixelGrabber (image, 538 0, 0, -1, -1, true); 539 try { 540 pg.grabPixels(); 541 } catch (InterruptedException e) { 542 throw new IOException ( 543 "java.awt.Image Interrupted waiting for pixels!"); 544 } 545 if ((pg.getStatus() & java.awt.image.ImageObserver.ABORT) != 0) { 546 throw new IOException ("java.awt.Image fetch aborted or errored"); 547 } 548 int w = pg.getWidth(); 549 int h = pg.getHeight(); 550 int[] pixels = (int[]) pg.getPixels(); 551 if (forceBW) { 552 int byteWidth = (w / 8) + ((w & 7) != 0 ? 1 : 0); 553 byte[] pixelsByte = new byte[byteWidth * h]; 554 555 int index = 0; 556 int size = h * w; 557 int transColor = 1; 558 if (color != null) { 559 transColor = (color.getRed() + color.getGreen() 560 + color.getBlue() < 384) ? 0 : 1; 561 } 562 int transparency[] = null; 563 int cbyte = 0x80; 564 int wMarker = 0; 565 int currByte = 0; 566 if (color != null) { 567 for (int j = 0; j < size; j++) { 568 int alpha = (pixels[j] >> 24) & 0xff; 569 if (alpha < 250) { 570 if (transColor == 1) 571 currByte |= cbyte; 572 } else { 573 if ((pixels[j] & 0x888) != 0) 574 currByte |= cbyte; 575 } 576 cbyte >>= 1; 577 if (cbyte == 0 || wMarker + 1 >= w) { 578 pixelsByte[index++] = (byte) currByte; 579 cbyte = 0x80; 580 currByte = 0; 581 } 582 ++wMarker; 583 if (wMarker >= w) 584 wMarker = 0; 585 } 586 } else { 587 for (int j = 0; j < size; j++) { 588 if (transparency == null) { 589 int alpha = (pixels[j] >> 24) & 0xff; 590 if (alpha == 0) { 591 transparency = new int[2]; 592 transparency[0] = transparency[1] = ((pixels[j] & 0x888) != 0) ? 1 593 : 0; 594 } 595 } 596 if ((pixels[j] & 0x888) != 0) 597 currByte |= cbyte; 598 cbyte >>= 1; 599 if (cbyte == 0 || wMarker + 1 >= w) { 600 pixelsByte[index++] = (byte) currByte; 601 cbyte = 0x80; 602 currByte = 0; 603 } 604 ++wMarker; 605 if (wMarker >= w) 606 wMarker = 0; 607 } 608 } 609 return Image.getInstance(w, h, 1, 1, pixelsByte, transparency); 610 } else { 611 byte[] pixelsByte = new byte[w * h * 3]; 612 byte[] smask = null; 613 614 int index = 0; 615 int size = h * w; 616 int red = 255; 617 int green = 255; 618 int blue = 255; 619 if (color != null) { 620 red = color.getRed(); 621 green = color.getGreen(); 622 blue = color.getBlue(); 623 } 624 int transparency[] = null; 625 if (color != null) { 626 for (int j = 0; j < size; j++) { 627 int alpha = (pixels[j] >> 24) & 0xff; 628 if (alpha < 250) { 629 pixelsByte[index++] = (byte) red; 630 pixelsByte[index++] = (byte) green; 631 pixelsByte[index++] = (byte) blue; 632 } else { 633 pixelsByte[index++] = (byte) ((pixels[j] >> 16) & 0xff); 634 pixelsByte[index++] = (byte) ((pixels[j] >> 8) & 0xff); 635 pixelsByte[index++] = (byte) ((pixels[j]) & 0xff); 636 } 637 } 638 } else { 639 int transparentPixel = 0; 640 smask = new byte[w * h]; 641 boolean shades = false; 642 for (int j = 0; j < size; j++) { 643 byte alpha = smask[j] = (byte) ((pixels[j] >> 24) & 0xff); 644 645 if (!shades) { 646 if (alpha != 0 && alpha != -1) { 647 shades = true; 648 } else if (transparency == null) { 649 if (alpha == 0) { 650 transparentPixel = pixels[j] & 0xffffff; 651 transparency = new int[6]; 652 transparency[0] = transparency[1] = (transparentPixel >> 16) & 0xff; 653 transparency[2] = transparency[3] = (transparentPixel >> 8) & 0xff; 654 transparency[4] = transparency[5] = transparentPixel & 0xff; 655 } 656 } else if ((pixels[j] & 0xffffff) != transparentPixel) { 657 shades = true; 658 } 659 } 660 pixelsByte[index++] = (byte) ((pixels[j] >> 16) & 0xff); 661 pixelsByte[index++] = (byte) ((pixels[j] >> 8) & 0xff); 662 pixelsByte[index++] = (byte) ((pixels[j]) & 0xff); 663 } 664 if (shades) 665 transparency = null; 666 else 667 smask = null; 668 } 669 Image img = Image.getInstance(w, h, 3, 8, pixelsByte, transparency); 670 if (smask != null) { 671 Image sm = Image.getInstance(w, h, 1, 8, smask); 672 try { 673 sm.makeMask(); 674 img.setImageMask(sm); 675 } catch (DocumentException de) { 676 throw new ExceptionConverter(de); 677 } 678 } 679 return img; 680 } 681 } 682 683 697 public static Image getInstance(java.awt.Image image, java.awt.Color color) 698 throws BadElementException, IOException { 699 return Image.getInstance(image, color, false); 700 } 701 702 717 public static Image getInstance(PdfWriter writer, java.awt.Image awtImage, float quality) throws BadElementException, IOException { 718 return getInstance(new PdfContentByte(writer), awtImage, quality); 719 } 720 721 736 public static Image getInstance(PdfContentByte cb, java.awt.Image awtImage, float quality) throws BadElementException, IOException { 737 java.awt.image.PixelGrabber pg = new java.awt.image.PixelGrabber (awtImage, 738 0, 0, -1, -1, true); 739 try { 740 pg.grabPixels(); 741 } catch (InterruptedException e) { 742 throw new IOException ( 743 "java.awt.Image Interrupted waiting for pixels!"); 744 } 745 if ((pg.getStatus() & java.awt.image.ImageObserver.ABORT) != 0) { 746 throw new IOException ("java.awt.Image fetch aborted or errored"); 747 } 748 int w = pg.getWidth(); 749 int h = pg.getHeight(); 750 PdfTemplate tp = cb.createTemplate(w, h); 751 Graphics2D g2d = tp.createGraphics(w, h, true, quality); 752 g2d.drawImage(awtImage, 0, 0, null); 753 g2d.dispose(); 754 return getInstance(tp); 755 } 756 757 759 764 private PdfIndirectReference directReference; 765 766 |