You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.3 KiB

  1. package com.sothr.imagetools.hash.util
  2. import java.awt.image.{BufferedImage, ColorConvertOp, DataBufferByte}
  3. import grizzled.slf4j.Logging
  4. import net.coobird.thumbnailator.Thumbnails
  5. object ImageUtil extends Logging {
  6. /**
  7. * Quickly convert an image to grayscale
  8. *
  9. * @param image image to convert to greyscale
  10. * @return
  11. */
  12. def convertToGray(image: BufferedImage): BufferedImage = {
  13. val grayImage = new BufferedImage(image.getWidth, image.getHeight, BufferedImage.TYPE_BYTE_GRAY)
  14. val op = new ColorConvertOp(
  15. image.getColorModel.getColorSpace,
  16. grayImage.getColorModel.getColorSpace,
  17. null
  18. )
  19. op.filter(image, grayImage)
  20. }
  21. def resize(image: BufferedImage, size: Int, forced: Boolean = false): BufferedImage = {
  22. //debug(s"Resizing an image to size: ${size}x${size} forced: $forced")
  23. if (forced) {
  24. Thumbnails.of(image).forceSize(size, size).asBufferedImage
  25. } else {
  26. Thumbnails.of(image).size(size, size).asBufferedImage
  27. }
  28. }
  29. /**
  30. * Get the raw data for an image
  31. * Convert a buffered image into a 2d pixel data array
  32. *
  33. * @param image image to convert without using RGB
  34. * @return
  35. */
  36. def getImageData(image: BufferedImage): Array[Array[Int]] = {
  37. val pixels = image.getRaster.getDataBuffer.asInstanceOf[DataBufferByte].getData
  38. val numPixels = pixels.length
  39. val width = image.getWidth
  40. val height = image.getHeight
  41. val isSingleChannel = if (numPixels == (width * height)) true else false
  42. val hasAlphaChannel = image.getAlphaRaster != null
  43. //debug(s"Converting image to 2d. width:$width height:$height")
  44. val result = Array.ofDim[Int](height, width)
  45. if (isSingleChannel) {
  46. //debug(s"Processing Single Channel Image")
  47. val pixelLength = 1
  48. var row = 0
  49. var col = 0
  50. //debug(s"Processing pixels 0 until $numPixels by $pixelLength")
  51. for (pixel <- 0 until numPixels by pixelLength) {
  52. //debug(s"Processing pixel: $pixel/${numPixels - 1}")
  53. val argb: Int = pixels(pixel).toInt //singleChannel
  54. //debug(s"Pixel data: $argb")
  55. result(row)(col) = argb
  56. col += 1
  57. if (col == width) {
  58. col = 0
  59. row += 1
  60. }
  61. }
  62. }
  63. else if (hasAlphaChannel) {
  64. //debug(s"Processing Four Channel Image")
  65. val pixelLength = 4
  66. var row = 0
  67. var col = 0
  68. //debug(s"Processing pixels 0 until $numPixels by $pixelLength")
  69. for (pixel <- 0 until numPixels by pixelLength) {
  70. //debug(s"Processing pixel: $pixel/${numPixels - 1}")
  71. var argb: Int = 0
  72. argb += pixels(pixel).toInt << 24 //alpha
  73. argb += pixels(pixel + 1).toInt //blue
  74. argb += pixels(pixel + 2).toInt << 8 //green
  75. argb += pixels(pixel + 3).toInt << 16 //red
  76. result(row)(col) = argb
  77. col += 1
  78. if (col == width) {
  79. col = 0
  80. row += 1
  81. }
  82. }
  83. } else {
  84. //debug(s"Processing Three Channel Image")
  85. val pixelLength = 3
  86. var row = 0
  87. var col = 0
  88. //debug(s"Processing pixels 0 until $numPixels by $pixelLength")
  89. for (pixel <- 0 until numPixels by pixelLength) {
  90. //debug(s"Processing pixel: $pixel/${numPixels - 1}")
  91. var argb: Int = 0
  92. argb += -16777216; // 255 alpha
  93. argb += pixels(pixel).toInt //blue
  94. argb += pixels(pixel + 1).toInt << 8 //green
  95. argb += pixels(pixel + 2).toInt << 16 //red
  96. result(row)(col) = argb
  97. col += 1
  98. if (col == width) {
  99. col = 0
  100. row += 1
  101. }
  102. }
  103. }
  104. result
  105. }
  106. }