package com.sothr.imagetools.hash.util import java.awt.image.{BufferedImage, ColorConvertOp, DataBufferByte} import grizzled.slf4j.Logging import net.coobird.thumbnailator.Thumbnails object ImageUtil extends Logging { /** * Quickly convert an image to grayscale * * @param image image to convert to greyscale * @return */ def convertToGray(image: BufferedImage): BufferedImage = { val grayImage = new BufferedImage(image.getWidth, image.getHeight, BufferedImage.TYPE_BYTE_GRAY) val op = new ColorConvertOp( image.getColorModel.getColorSpace, grayImage.getColorModel.getColorSpace, null ) op.filter(image, grayImage) } def resize(image: BufferedImage, size: Int, forced: Boolean = false): BufferedImage = { //debug(s"Resizing an image to size: ${size}x${size} forced: $forced") if (forced) { Thumbnails.of(image).forceSize(size, size).asBufferedImage } else { Thumbnails.of(image).size(size, size).asBufferedImage } } /** * Get the raw data for an image * Convert a buffered image into a 2d pixel data array * * @param image image to convert without using RGB * @return */ def getImageData(image: BufferedImage): Array[Array[Int]] = { val pixels = image.getRaster.getDataBuffer.asInstanceOf[DataBufferByte].getData val numPixels = pixels.length val width = image.getWidth val height = image.getHeight val isSingleChannel = if (numPixels == (width * height)) true else false val hasAlphaChannel = image.getAlphaRaster != null //debug(s"Converting image to 2d. width:$width height:$height") val result = Array.ofDim[Int](height, width) if (isSingleChannel) { //debug(s"Processing Single Channel Image") val pixelLength = 1 var row = 0 var col = 0 //debug(s"Processing pixels 0 until $numPixels by $pixelLength") for (pixel <- 0 until numPixels by pixelLength) { //debug(s"Processing pixel: $pixel/${numPixels - 1}") val argb: Int = pixels(pixel).toInt //singleChannel //debug(s"Pixel data: $argb") result(row)(col) = argb col += 1 if (col == width) { col = 0 row += 1 } } } else if (hasAlphaChannel) { //debug(s"Processing Four Channel Image") val pixelLength = 4 var row = 0 var col = 0 //debug(s"Processing pixels 0 until $numPixels by $pixelLength") for (pixel <- 0 until numPixels by pixelLength) { //debug(s"Processing pixel: $pixel/${numPixels - 1}") var argb: Int = 0 argb += pixels(pixel).toInt << 24 //alpha argb += pixels(pixel + 1).toInt //blue argb += pixels(pixel + 2).toInt << 8 //green argb += pixels(pixel + 3).toInt << 16 //red result(row)(col) = argb col += 1 if (col == width) { col = 0 row += 1 } } } else { //debug(s"Processing Three Channel Image") val pixelLength = 3 var row = 0 var col = 0 //debug(s"Processing pixels 0 until $numPixels by $pixelLength") for (pixel <- 0 until numPixels by pixelLength) { //debug(s"Processing pixel: $pixel/${numPixels - 1}") var argb: Int = 0 argb += -16777216; // 255 alpha argb += pixels(pixel).toInt //blue argb += pixels(pixel + 1).toInt << 8 //green argb += pixels(pixel + 2).toInt << 16 //red result(row)(col) = argb col += 1 if (col == width) { col = 0 row += 1 } } } result } }