(BufferedImage img,
int targetWidth, int targetHeight)
| 274 | // plus a fix to deal with an infinite loop if images are expanded. |
| 275 | // https://github.com/processing/processing/issues/1501 |
| 276 | static private BufferedImage shrinkImage(BufferedImage img, |
| 277 | int targetWidth, int targetHeight) { |
| 278 | int type = (img.getTransparency() == Transparency.OPAQUE) ? |
| 279 | BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; |
| 280 | BufferedImage outgoing = img; |
| 281 | BufferedImage scratchImage = null; |
| 282 | Graphics2D g2 = null; |
| 283 | int prevW = outgoing.getWidth(); |
| 284 | int prevH = outgoing.getHeight(); |
| 285 | boolean isTranslucent = img.getTransparency() != Transparency.OPAQUE; |
| 286 | |
| 287 | // Use multi-step technique: start with original size, then scale down in |
| 288 | // multiple passes with drawImage() until the target size is reached |
| 289 | int w = img.getWidth(); |
| 290 | int h = img.getHeight(); |
| 291 | |
| 292 | do { |
| 293 | if (w > targetWidth) { |
| 294 | w /= 2; |
| 295 | // if this is the last step, do the exact size |
| 296 | if (w < targetWidth) { |
| 297 | w = targetWidth; |
| 298 | } |
| 299 | } else { //if (targetWidth >= w) { |
| 300 | w = targetWidth; |
| 301 | } |
| 302 | if (h > targetHeight) { |
| 303 | h /= 2; |
| 304 | if (h < targetHeight) { |
| 305 | h = targetHeight; |
| 306 | } |
| 307 | } else { //if (targetHeight >= h) { |
| 308 | h = targetHeight; |
| 309 | } |
| 310 | if (scratchImage == null || isTranslucent) { |
| 311 | // Use a single scratch buffer for all iterations and then copy |
| 312 | // to the final, correctly-sized image before returning |
| 313 | scratchImage = new BufferedImage(w, h, type); |
| 314 | g2 = scratchImage.createGraphics(); |
| 315 | } |
| 316 | g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, |
| 317 | RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
| 318 | g2.drawImage(outgoing, 0, 0, w, h, 0, 0, prevW, prevH, null); |
| 319 | prevW = w; |
| 320 | prevH = h; |
| 321 | outgoing = scratchImage; |
| 322 | } while (w != targetWidth || h != targetHeight); |
| 323 | |
| 324 | //if (g2 != null) { |
| 325 | g2.dispose(); |
| 326 | //} |
| 327 | |
| 328 | // If we used a scratch buffer that is larger than our target size, |
| 329 | // create an image of the right size and copy the results into it |
| 330 | if (targetWidth != outgoing.getWidth() || |
| 331 | targetHeight != outgoing.getHeight()) { |
| 332 | scratchImage = new BufferedImage(targetWidth, targetHeight, type); |
| 333 | g2 = scratchImage.createGraphics(); |
no test coverage detected