(BufferedImage img,
int targetWidth, int targetHeight)
| 164 | // plus a fix to deal with an infinite loop if images are expanded. |
| 165 | // https://github.com/processing/processing/issues/1501 |
| 166 | static private BufferedImage shrinkImage(BufferedImage img, |
| 167 | int targetWidth, int targetHeight) { |
| 168 | int type = (img.getTransparency() == Transparency.OPAQUE) ? |
| 169 | BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; |
| 170 | BufferedImage outgoing = img; |
| 171 | BufferedImage scratchImage = null; |
| 172 | Graphics2D g2 = null; |
| 173 | int prevW = outgoing.getWidth(); |
| 174 | int prevH = outgoing.getHeight(); |
| 175 | boolean isTranslucent = img.getTransparency() != Transparency.OPAQUE; |
| 176 | |
| 177 | // Use multi-step technique: start with original size, then scale down in |
| 178 | // multiple passes with drawImage() until the target size is reached |
| 179 | int w = img.getWidth(); |
| 180 | int h = img.getHeight(); |
| 181 | |
| 182 | do { |
| 183 | if (w > targetWidth) { |
| 184 | w /= 2; |
| 185 | // if this is the last step, do the exact size |
| 186 | if (w < targetWidth) { |
| 187 | w = targetWidth; |
| 188 | } |
| 189 | } else if (targetWidth >= w) { |
| 190 | w = targetWidth; |
| 191 | } |
| 192 | if (h > targetHeight) { |
| 193 | h /= 2; |
| 194 | if (h < targetHeight) { |
| 195 | h = targetHeight; |
| 196 | } |
| 197 | } else if (targetHeight >= h) { |
| 198 | h = targetHeight; |
| 199 | } |
| 200 | if (scratchImage == null || isTranslucent) { |
| 201 | // Use a single scratch buffer for all iterations and then copy |
| 202 | // to the final, correctly-sized image before returning |
| 203 | scratchImage = new BufferedImage(w, h, type); |
| 204 | g2 = scratchImage.createGraphics(); |
| 205 | } |
| 206 | g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, |
| 207 | RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
| 208 | g2.drawImage(outgoing, 0, 0, w, h, 0, 0, prevW, prevH, null); |
| 209 | prevW = w; |
| 210 | prevH = h; |
| 211 | outgoing = scratchImage; |
| 212 | } while (w != targetWidth || h != targetHeight); |
| 213 | |
| 214 | if (g2 != null) { |
| 215 | g2.dispose(); |
| 216 | } |
| 217 | |
| 218 | // If we used a scratch buffer that is larger than our target size, |
| 219 | // create an image of the right size and copy the results into it |
| 220 | if (targetWidth != outgoing.getWidth() || |
| 221 | targetHeight != outgoing.getHeight()) { |
| 222 | scratchImage = new BufferedImage(targetWidth, targetHeight, type); |
| 223 | g2 = scratchImage.createGraphics(); |
no test coverage detected