|
|
package com.sothr.imagetools.engine.image
import java.awt.image.BufferedImage import java.io.{File, IOException} import javax.imageio.ImageIO
import com.sothr.imagetools.engine.AppConfig import com.sothr.imagetools.engine.dao.ImageDAO import com.sothr.imagetools.engine.util.{PropertiesService, PropertyEnum} import com.sothr.imagetools.engine.vo.ImageHashVO import com.sothr.imagetools.hash.{HashService, ImageHash} import com.sothr.imagetools.hash.util.ImageUtil import grizzled.slf4j.Logging import net.sf.ehcache.Element import org.hibernate.HibernateException
object ImageService extends Logging {
val imageCache = AppConfig.cacheManager.getCache("images") private val imageDAO = new ImageDAO()
def getImage(file: File): Image = { try { val image = lookupImage(file) if (image != null) { debug(s"${file.getAbsolutePath} was already processed") return image } else { debug(s"Processing image: ${file.getAbsolutePath}") val bufferedImage = ImageIO.read(file) val hashes = HashService.getImageHashes( PropertiesService.aHashSettings, PropertiesService.dHashSettings, PropertiesService.pHashSettings, bufferedImage, file.getAbsolutePath)
var thumbnailPath = lookupThumbnailPath(hashes.fileHash) if (thumbnailPath == null) thumbnailPath = getThumbnail(bufferedImage, hashes.fileHash) val imageSize = { (bufferedImage.getWidth, bufferedImage.getHeight) } val image = new Image(file.getAbsolutePath, thumbnailPath, imageSize, ImageService.convertToImageHashVO(hashes)) debug(s"Created image: $image") return saveImage(image) } } catch { case ioe: IOException => error(s"Error processing ${file.getAbsolutePath}... ${ioe.getMessage}") case ex: Exception => error(s"Error processing ${file.getAbsolutePath}... ${ex.getMessage}", ex) } null }
def convertToImageHashDTO(imageHashVO: ImageHashVO): ImageHash = { new ImageHash(imageHashVO.ahash, imageHashVO.dhash, imageHashVO.phash, imageHashVO.fileHash) }
def convertToImageHashVO(imageHashDTO: ImageHash): ImageHashVO = { new ImageHashVO(imageHashDTO.ahash, imageHashDTO.dhash, imageHashDTO.phash, imageHashDTO.fileHash) }
private def lookupImage(file: File): Image = { var image: Image = null var found = false //get from memory cache if possible
try { if (imageCache.isKeyInCache(file.getAbsolutePath)) { image = imageCache.get(file.getAbsolutePath).getObjectValue.asInstanceOf[Image] found = true } } catch { case npe: NullPointerException => debug(s"\'${file.getAbsolutePath}\' was supposed to be in the cache, but was not") } //get from datastore if possible
if (!found) { try { val tempImage = imageDAO.find(file.getAbsolutePath) if (tempImage != null) image = tempImage } catch { case ex: Exception => error(s"Error looking up \'${file.getAbsolutePath}\' was supposed to be in the database, but was not", ex) } } image }
private def saveImage(image: Image): Image = { //save to cache
imageCache.put(new Element(image.imagePath, image)) //save to datastore
try { imageDAO.save(image) } catch { case ex: Exception => error(s"Error saving \'${image.imagePath}\' to database", ex) } image }
def lookupThumbnailPath(md5: String): String = { var thumbPath: String = null if (md5 != null) { //check for the actual file
val checkPath = calculateThumbPath(md5) if (new File(checkPath).exists) thumbPath = checkPath } else { error("Null md5 passed in") } thumbPath }
def calculateThumbPath(md5: String): String = { //break the path down into 4 char parts
val subPath = md5.substring(0, 3) var path: String = s"${PropertiesService.get(PropertyEnum.ThumbnailDirectory.toString)}${PropertiesService.get(PropertyEnum.ThumbnailSize.toString)}/$subPath/" try { val dir = new File(path) if (!dir.exists()) dir.mkdirs() } catch { case ioe: IOException => error(s"Unable to create dirs for path: \'$path\'", ioe) } path += md5 + ".jpg" path }
def getThumbnail(image: BufferedImage, md5: String): String = { //create thumbnail
val thumb = ImageUtil.resize(image, PropertiesService.get(PropertyEnum.ThumbnailSize.toString).toInt, forced = false) //calculate path
val path = calculateThumbPath(md5) // save thumbnail to path
try { ImageIO.write(thumb, "png", new File(path)) debug(s"Wrote thumbnail to $path") } catch { case ioe: IOException => error(s"Unable to save thumbnail to $path", ioe) } // return path
path }
def deleteImage(image: Image) = { debug(s"Attempting to delete all traces of image: ${image.getImagePath}") try { val imageFile = new File(image.imagePath) //try to delete the file
imageFile.delete() //purge the file from the database and cache
this.imageCache.remove(imageFile.getAbsolutePath) this.imageDAO.delete(image) } catch { case se: SecurityException => error(s"Unable to delete file: ${image.getImagePath} due to a security exception", se) case ise: IllegalStateException => error(s"Unable to delete file: ${image.getImagePath} due to an illegal state exception", ise) case he: HibernateException => error(s"Unable to delete file: ${image.getImagePath} due to a hibernate exception", he) } } }
|