(BufferedImage img,
int targetWidth, int targetHeight)
| 583 | // plus a fix to deal with an infinite loop if images are expanded. |
| 584 | // http://code.google.com/p/processing/issues/detail?id=1463 |
| 585 | static private BufferedImage shrinkImage(BufferedImage img, |
| 586 | int targetWidth, int targetHeight) { |
| 587 | int type = (img.getTransparency() == Transparency.OPAQUE) ? |
| 588 | BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; |
| 589 | BufferedImage outgoing = img; |
| 590 | BufferedImage scratchImage = null; |
| 591 | Graphics2D g2 = null; |
| 592 | int prevW = outgoing.getWidth(); |
| 593 | int prevH = outgoing.getHeight(); |
| 594 | boolean isTranslucent = img.getTransparency() != Transparency.OPAQUE; |
| 595 | |
| 596 | // Use multi-step technique: start with original size, then scale down in |
| 597 | // multiple passes with drawImage() until the target size is reached |
| 598 | int w = img.getWidth(); |
| 599 | int h = img.getHeight(); |
| 600 | |
| 601 | do { |
| 602 | if (w > targetWidth) { |
| 603 | w /= 2; |
| 604 | // if this is the last step, do the exact size |
| 605 | if (w < targetWidth) { |
| 606 | w = targetWidth; |
| 607 | } |
| 608 | } else if (targetWidth >= w) { |
| 609 | w = targetWidth; |
| 610 | } |
| 611 | if (h > targetHeight) { |
| 612 | h /= 2; |
| 613 | if (h < targetHeight) { |
| 614 | h = targetHeight; |
| 615 | } |
| 616 | } else if (targetHeight >= h) { |
| 617 | h = targetHeight; |
| 618 | } |
| 619 | if (scratchImage == null || isTranslucent) { |
| 620 | // Use a single scratch buffer for all iterations and then copy |
| 621 | // to the final, correctly-sized image before returning |
| 622 | scratchImage = new BufferedImage(w, h, type); |
| 623 | g2 = scratchImage.createGraphics(); |
| 624 | } |
| 625 | g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, |
| 626 | RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
| 627 | g2.drawImage(outgoing, 0, 0, w, h, 0, 0, prevW, prevH, null); |
| 628 | prevW = w; |
| 629 | prevH = h; |
| 630 | outgoing = scratchImage; |
| 631 | } while (w != targetWidth || h != targetHeight); |
| 632 | |
| 633 | if (g2 != null) { |
| 634 | g2.dispose(); |
| 635 | } |
| 636 | |
| 637 | // If we used a scratch buffer that is larger than our target size, |
| 638 | // create an image of the right size and copy the results into it |
| 639 | if (targetWidth != outgoing.getWidth() || |
| 640 | targetHeight != outgoing.getHeight()) { |
| 641 | scratchImage = new BufferedImage(targetWidth, targetHeight, type); |
| 642 | g2 = scratchImage.createGraphics(); |
no test coverage detected