216 float total = 0.0f; 217 218 for (int i = -radius; i <= radius; i++) { 219 float distance = i * i; 220 int index = i + radius; 221 data[index] = (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot; 222 total += data[index]; 223 } 224 225 for (int i = 0; i < data.length; i++) { 226 data[i] /= total; 227 } 228 229 return data; 230 } 231 232 // ================================================================================================================= 233 // Get/Set Pixels helper methods 234 235 /** 236 * <p>Returns an array of pixels, stored as integers, from a <code>BufferedImage</code>. The pixels are grabbed from 237 * a rectangular area defined by a location and two dimensions. Calling this method on an image of type different 238 * from <code>BufferedImage.TYPE_INT_ARGB</code> and <code>BufferedImage.TYPE_INT_RGB</code> will unmanage the 239 * image.</p> 240 * 241 * @param img the source image 242 * @param x the x location at which to start grabbing pixels 243 * @param y the y location at which to start grabbing pixels 244 * @param w the width of the rectangle of pixels to grab 245 * @param h the height of the rectangle of pixels to grab 246 * @param pixels a pre-allocated array of pixels of size w*h; can be null 247 * @return <code>pixels</code> if non-null, a new array of integers otherwise 248 * @throws IllegalArgumentException is <code>pixels</code> is non-null and of length < w*h 249 */ 250 static byte[] getPixels(BufferedImage img, 251 int x, int y, int w, int h, byte[] pixels) { 252 if (w == 0 || h == 0) { 253 return new byte[0]; 254 } 255 256 if (pixels == null) { 257 pixels = new byte[w * h]; 258 } else if (pixels.length < w * h) { 259 throw new IllegalArgumentException("pixels array must have a length >= w*h"); 260 } 261 262 int imageType = img.getType(); 263 if (imageType == BufferedImage.TYPE_BYTE_GRAY) { 264 Raster raster = img.getRaster(); 265 return (byte[]) raster.getDataElements(x, y, w, h, pixels); 266 } else { 267 throw new IllegalArgumentException("Only type BYTE_GRAY is supported"); 268 } 269 } 270 271 /** 272 * <p>Writes a rectangular area of pixels in the destination <code>BufferedImage</code>. Calling this method on an 273 * image of type different from <code>BufferedImage.TYPE_INT_ARGB</code> and <code>BufferedImage.TYPE_INT_RGB</code> 274 * will unmanage the image.</p> 275 * 276 * @param img the destination image 277 * @param x the x location at which to start storing pixels 278 * @param y the y location at which to start storing pixels 279 * @param w the width of the rectangle of pixels to store 280 * @param h the height of the rectangle of pixels to store 281 * @param pixels an array of pixels, stored as integers 282 * @throws IllegalArgumentException is <code>pixels</code> is non-null and of length < w*h 283 */ 284 static void setPixels(BufferedImage img, 285 int x, int y, int w, int h, byte[] pixels) { 286 if (pixels == null || w == 0 || h == 0) { 287 return; 288 } else if (pixels.length < w * h) { 289 throw new IllegalArgumentException("pixels array must have a length >= w*h"); 290 } 291 int imageType = img.getType(); 292 if (imageType == BufferedImage.TYPE_BYTE_GRAY) { 293 WritableRaster raster = img.getRaster(); 294 raster.setDataElements(x, y, w, h, pixels); 295 } else { 296 throw new IllegalArgumentException("Only type BYTE_GRAY is supported"); 297 } 298 } 299 300 /** 301 * <p>Returns an array of pixels, stored as integers, from a 302 * <code>BufferedImage</code>. The pixels are grabbed from a rectangular 303 * area defined by a location and two dimensions. Calling this method on 304 * an image of type different from <code>BufferedImage.TYPE_INT_ARGB</code> 305 * and <code>BufferedImage.TYPE_INT_RGB</code> will unmanage the image.</p> 306 * 307 * @param img the source image 308 * @param x the x location at which to start grabbing pixels 309 * @param y the y location at which to start grabbing pixels 310 * @param w the width of the rectangle of pixels to grab 311 * @param h the height of the rectangle of pixels to grab 312 * @param pixels a pre-allocated array of pixels of size w*h; can be null 313 * @return <code>pixels</code> if non-null, a new array of integers 314 * otherwise 315 * @throws IllegalArgumentException is <code>pixels</code> is non-null and 316 * of length < w*h 317 */ 318 public static int[] getPixels(BufferedImage img, 319 int x, int y, int w, int h, int[] pixels) { 320 if (w == 0 || h == 0) { 321 return new int[0]; 322 } 323 324 if (pixels == null) { 325 pixels = new int[w * h]; 326 } else if (pixels.length < w * h) { 327 throw new IllegalArgumentException("pixels array must have a length" + 328 " >= w*h"); 329 } 330 331 int imageType = img.getType(); 332 if (imageType == BufferedImage.TYPE_INT_ARGB || 333 imageType == BufferedImage.TYPE_INT_RGB) { 334 Raster raster = img.getRaster(); 335 return (int[]) raster.getDataElements(x, y, w, h, pixels); 336 } 337 338 // Unmanages the image 339 return img.getRGB(x, y, w, h, pixels, 0, w); 340 } 341 342 /** 343 * <p>Writes a rectangular area of pixels in the destination 344 * <code>BufferedImage</code>. Calling this method on 345 * an image of type different from <code>BufferedImage.TYPE_INT_ARGB</code> 346 * and <code>BufferedImage.TYPE_INT_RGB</code> will unmanage the image.</p> 347 * 348 * @param img the destination image 349 * @param x the x location at which to start storing pixels 350 * @param y the y location at which to start storing pixels 351 * @param w the width of the rectangle of pixels to store 352 * @param h the height of the rectangle of pixels to store 353 * @param pixels an array of pixels, stored as integers 354 * @throws IllegalArgumentException is <code>pixels</code> is non-null and 355 * of length < w*h 356 */ 357 public static void setPixels(BufferedImage img, 358 int x, int y, int w, int h, int[] pixels) { 359 if (pixels == null || w == 0 || h == 0) { 360 return; 361 } else if (pixels.length < w * h) { 362 throw new IllegalArgumentException("pixels array must have a length" + 363 " >= w*h"); 364 } 365 366 int imageType = img.getType(); 367 if (imageType == BufferedImage.TYPE_INT_ARGB || 368 imageType == BufferedImage.TYPE_INT_RGB) { 369 WritableRaster raster = img.getRaster(); 370 raster.setDataElements(x, y, w, h, pixels); 371 } else { 372 // Unmanages the image 373 img.setRGB(x, y, w, h, pixels, 0, w); 374 } 375 } 376 377 /** 378 * <p>Returns a new <code>BufferedImage</code> using the same color model 379 * as the image passed as a parameter. The returned image is only compatible 380 * with the image passed as a parameter. This does not mean the returned 381 * image is compatible with the hardware.</p> 382 * 383 * @param image the reference image from which the color model of the new 384 * image is obtained 385 * @return a new <code>BufferedImage</code>, compatible with the color model 386 * of <code>image</code> 387 */ 388 public static BufferedImage createColorModelCompatibleImage(BufferedImage image) { 389 ColorModel cm = image.getColorModel(); 390 return new BufferedImage(cm, 391 cm.createCompatibleWritableRaster(image.getWidth(), 392 image.getHeight()), 393 cm.isAlphaPremultiplied(), null); 394 } 395 396 /** 397 * <p>Returns a new translucent compatible image of the specified width and 398 * height. That is, the returned <code>BufferedImage</code> is compatible with 399 * the graphics hardware. If the method is called in a headless 400 * environment, then the returned BufferedImage will be compatible with 401 * the source image.</p> 402 * 403 * @param width the width of the new image 404 * @param height the height of the new image 405 * @return a new translucent compatible <code>BufferedImage</code> of the 406 * specified width and height 407 */ 408 public static BufferedImage createCompatibleTranslucentImage(int width, 409 int height) { 410 return isHeadless() ? 411 new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) : 412 getGraphicsConfiguration().createCompatibleImage(width, height, 413 Transparency.TRANSLUCENT); 414 } 415 416 private static boolean isHeadless() { 417 return GraphicsEnvironment.isHeadless(); 418 } 419 420 // Returns the graphics configuration for the primary screen 421 private static GraphicsConfiguration getGraphicsConfiguration() { 422 return GraphicsEnvironment.getLocalGraphicsEnvironment(). 423 getDefaultScreenDevice().getDefaultConfiguration(); 424 } 425 | 216 float total = 0.0f; 217 218 for (int i = -radius; i <= radius; i++) { 219 float distance = i * i; 220 int index = i + radius; 221 data[index] = (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot; 222 total += data[index]; 223 } 224 225 for (int i = 0; i < data.length; i++) { 226 data[i] /= total; 227 } 228 229 return data; 230 } 231 232 // ================================================================================================================= 233 // Get/Set Pixels helper methods 234 235 /** 236 * <p>Returns an array of pixels, stored as integers, from a {@code BufferedImage}. The pixels are grabbed from 237 * a rectangular area defined by a location and two dimensions. Calling this method on an image of type different 238 * from {@code BufferedImage.TYPE_INT_ARGB} and {@code BufferedImage.TYPE_INT_RGB} will unmanage the 239 * image.</p> 240 * 241 * @param img the source image 242 * @param x the x location at which to start grabbing pixels 243 * @param y the y location at which to start grabbing pixels 244 * @param w the width of the rectangle of pixels to grab 245 * @param h the height of the rectangle of pixels to grab 246 * @param pixels a pre-allocated array of pixels of size w*h; can be null 247 * @return {@code pixels} if non-null, a new array of integers otherwise 248 * @throws IllegalArgumentException is {@code pixels} is non-null and of length < w*h 249 */ 250 static byte[] getPixels(BufferedImage img, 251 int x, int y, int w, int h, byte[] pixels) { 252 if (w == 0 || h == 0) { 253 return new byte[0]; 254 } 255 256 if (pixels == null) { 257 pixels = new byte[w * h]; 258 } else if (pixels.length < w * h) { 259 throw new IllegalArgumentException("pixels array must have a length >= w*h"); 260 } 261 262 int imageType = img.getType(); 263 if (imageType == BufferedImage.TYPE_BYTE_GRAY) { 264 Raster raster = img.getRaster(); 265 return (byte[]) raster.getDataElements(x, y, w, h, pixels); 266 } else { 267 throw new IllegalArgumentException("Only type BYTE_GRAY is supported"); 268 } 269 } 270 271 /** 272 * <p>Writes a rectangular area of pixels in the destination {@code BufferedImage}. Calling this method on an 273 * image of type different from {@code BufferedImage.TYPE_INT_ARGB} and {@code BufferedImage.TYPE_INT_RGB} 274 * will unmanage the image.</p> 275 * 276 * @param img the destination image 277 * @param x the x location at which to start storing pixels 278 * @param y the y location at which to start storing pixels 279 * @param w the width of the rectangle of pixels to store 280 * @param h the height of the rectangle of pixels to store 281 * @param pixels an array of pixels, stored as integers 282 * @throws IllegalArgumentException is {@code pixels} is non-null and of length < w*h 283 */ 284 static void setPixels(BufferedImage img, 285 int x, int y, int w, int h, byte[] pixels) { 286 if (pixels == null || w == 0 || h == 0) { 287 return; 288 } else if (pixels.length < w * h) { 289 throw new IllegalArgumentException("pixels array must have a length >= w*h"); 290 } 291 int imageType = img.getType(); 292 if (imageType == BufferedImage.TYPE_BYTE_GRAY) { 293 WritableRaster raster = img.getRaster(); 294 raster.setDataElements(x, y, w, h, pixels); 295 } else { 296 throw new IllegalArgumentException("Only type BYTE_GRAY is supported"); 297 } 298 } 299 300 /** 301 * <p>Returns an array of pixels, stored as integers, from a 302 * {@code BufferedImage}. The pixels are grabbed from a rectangular 303 * area defined by a location and two dimensions. Calling this method on 304 * an image of type different from {@code BufferedImage.TYPE_INT_ARGB} 305 * and {@code BufferedImage.TYPE_INT_RGB} will unmanage the image.</p> 306 * 307 * @param img the source image 308 * @param x the x location at which to start grabbing pixels 309 * @param y the y location at which to start grabbing pixels 310 * @param w the width of the rectangle of pixels to grab 311 * @param h the height of the rectangle of pixels to grab 312 * @param pixels a pre-allocated array of pixels of size w*h; can be null 313 * @return {@code pixels} if non-null, a new array of integers 314 * otherwise 315 * @throws IllegalArgumentException is {@code pixels} is non-null and 316 * of length < w*h 317 */ 318 public static int[] getPixels(BufferedImage img, 319 int x, int y, int w, int h, int[] pixels) { 320 if (w == 0 || h == 0) { 321 return new int[0]; 322 } 323 324 if (pixels == null) { 325 pixels = new int[w * h]; 326 } else if (pixels.length < w * h) { 327 throw new IllegalArgumentException("pixels array must have a length" + 328 " >= w*h"); 329 } 330 331 int imageType = img.getType(); 332 if (imageType == BufferedImage.TYPE_INT_ARGB || 333 imageType == BufferedImage.TYPE_INT_RGB) { 334 Raster raster = img.getRaster(); 335 return (int[]) raster.getDataElements(x, y, w, h, pixels); 336 } 337 338 // Unmanages the image 339 return img.getRGB(x, y, w, h, pixels, 0, w); 340 } 341 342 /** 343 * <p>Writes a rectangular area of pixels in the destination 344 * {@code BufferedImage}. Calling this method on 345 * an image of type different from {@code BufferedImage.TYPE_INT_ARGB} 346 * and {@code BufferedImage.TYPE_INT_RGB} will unmanage the image.</p> 347 * 348 * @param img the destination image 349 * @param x the x location at which to start storing pixels 350 * @param y the y location at which to start storing pixels 351 * @param w the width of the rectangle of pixels to store 352 * @param h the height of the rectangle of pixels to store 353 * @param pixels an array of pixels, stored as integers 354 * @throws IllegalArgumentException is {@code pixels} is non-null and 355 * of length < w*h 356 */ 357 public static void setPixels(BufferedImage img, 358 int x, int y, int w, int h, int[] pixels) { 359 if (pixels == null || w == 0 || h == 0) { 360 return; 361 } else if (pixels.length < w * h) { 362 throw new IllegalArgumentException("pixels array must have a length" + 363 " >= w*h"); 364 } 365 366 int imageType = img.getType(); 367 if (imageType == BufferedImage.TYPE_INT_ARGB || 368 imageType == BufferedImage.TYPE_INT_RGB) { 369 WritableRaster raster = img.getRaster(); 370 raster.setDataElements(x, y, w, h, pixels); 371 } else { 372 // Unmanages the image 373 img.setRGB(x, y, w, h, pixels, 0, w); 374 } 375 } 376 377 /** 378 * <p>Returns a new {@code BufferedImage} using the same color model 379 * as the image passed as a parameter. The returned image is only compatible 380 * with the image passed as a parameter. This does not mean the returned 381 * image is compatible with the hardware.</p> 382 * 383 * @param image the reference image from which the color model of the new 384 * image is obtained 385 * @return a new {@code BufferedImage}, compatible with the color model 386 * of {@code image} 387 */ 388 public static BufferedImage createColorModelCompatibleImage(BufferedImage image) { 389 ColorModel cm = image.getColorModel(); 390 return new BufferedImage(cm, 391 cm.createCompatibleWritableRaster(image.getWidth(), 392 image.getHeight()), 393 cm.isAlphaPremultiplied(), null); 394 } 395 396 /** 397 * <p>Returns a new translucent compatible image of the specified width and 398 * height. That is, the returned {@code BufferedImage} is compatible with 399 * the graphics hardware. If the method is called in a headless 400 * environment, then the returned BufferedImage will be compatible with 401 * the source image.</p> 402 * 403 * @param width the width of the new image 404 * @param height the height of the new image 405 * @return a new translucent compatible {@code BufferedImage} of the 406 * specified width and height 407 */ 408 public static BufferedImage createCompatibleTranslucentImage(int width, 409 int height) { 410 return isHeadless() ? 411 new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) : 412 getGraphicsConfiguration().createCompatibleImage(width, height, 413 Transparency.TRANSLUCENT); 414 } 415 416 private static boolean isHeadless() { 417 return GraphicsEnvironment.isHeadless(); 418 } 419 420 // Returns the graphics configuration for the primary screen 421 private static GraphicsConfiguration getGraphicsConfiguration() { 422 return GraphicsEnvironment.getLocalGraphicsEnvironment(). 423 getDefaultScreenDevice().getDefaultConfiguration(); 424 } 425 |