Upload and resize images – Play 2.1 Scala Mongodb

This code is to upload and resize images. The image will be store onto MongoDB gridfs. The tested  code is working on Play 2.1 and mongodb 2.4. Resizing image is using imgscalr 4.2, Java Image Scaling Library. Connection to MongoDB is using Leon Salat.

1) Connection to MongoDB, follow step at Leon

2) Import imgscalr

project/build.scala

val appDependencies = Seq(
 // Add your project dependencies here,
 "org.imgscalr" % "imgscalr-lib" % "4.2"
)

val main = play.Project(appName, appVersion, appDependencies).settings(
 // Add your own project settings here 
 resolvers ++= Seq(
 "The Buzz Media Maven Repository" at "http://maven.thebuzzmedia.com"
 )
)

Using eclipse, download imgscalr library and import jar into the project path

3) Model

package models

import play.api.Play.current
import com.novus.salat.dao._
import com.mongodb.casbah.Imports._
import se.radley.plugin.salat._
import mongoContext._
import java.io.File
import play.api.mvc.SimpleResult

case class FileModel(
 id: ObjectId = new ObjectId,
 foi: ObjectId // file objectid
)

object FileModel extends ModelCompanion[FileModel, ObjectId]{
 val dao = new SalatDAO[FileModel, ObjectId](collection = mongoCollection("file")) {}

 // insert file into gridFS and save file object id into document
 def insertFile(photo:File, contentType:String) = {
 val gridFs = gridFS("photos")

 val uploadedFile = gridFs.createFile(photo)
 uploadedFile.contentType = contentType

 val f = FileModel(new ObjectId, uploadedFile._id.get)
 val s = FileModel.insert(f)
 uploadedFile.save()
 }
}

4) Controller

package controllers

import play.api._
import play.api.mvc._
import play.api.Play.current
import models._
import views._
import com.mongodb.casbah.Imports._
import se.radley.plugin.salat._
import java.text.SimpleDateFormat
import play.api.libs.iteratee.Enumerator
import java.awt.image.BufferedImage
import javax.imageio.ImageIO;
import org.imgscalr.Scalr

object FileController extends Controller {
 def index = Action { 
 Ok(html.upload.index(FileModel.findAll.toIterator))
 }

//upload photo
 def upload = Action(parse.multipartFormData) { implicit request =>
 request.body.file("photo") match {
 case Some(photo) =>
 // check if photo is type jpeg or gif
 if(checkIfPhoto(photo.contentType.get)){
 //get photo into BufferedImage
 var orImg = ImageIO.read(photo.ref.file)
 //Resize image
 var rsImg = Scalr.resize(orImg, 150)
 //set the resize image to file
 ImageIO.write(rsImg, "jpg", photo.ref.file)
 //insert photo
 FileModel.insertFile(photo.ref.file, photo.contentType.orNull)
 }
 Ok(html.upload.index(FileModel.findAll.toIterator))
 case None => BadRequest("no photo")
 }
 }

 // check if photo is type jpeg or gif
 def checkIfPhoto(file: String) = {
 file match{
 case "image/jpeg" => true
 case "image/gif" => true
 case _ => false
 }
 }

 //display photo
 def getPhoto(file: ObjectId) = Action {
 val gridFs = gridFS("photos")
 gridFs.findOne(Map("_id" -> file)) match {
 case Some(f) => SimpleResult(
 ResponseHeader(OK, Map(
 CONTENT_LENGTH -> f.length.toString,
 CONTENT_TYPE -> f.contentType.getOrElse(BINARY),
 DATE -> new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", java.util.Locale.US).format(f.uploadDate)
 )),
 Enumerator.fromStream(f.inputStream)
 )
 case None => NotFound
 }
 }

 //delete photo
 def deletePhoto(file: ObjectId, id: ObjectId) = Action {
 val gridFs = gridFS("photos")
 FileModel.removeById(id)
 gridFs.remove(file)
 Ok(html.upload.index(FileModel.findAll.toIterator))
 }
}

5) Route

GET 	/upload 		controllers.FileController.index
POST	/upload			controllers.FileController.upload
GET 	/photos/:file 		controllers.FileController.getPhoto(file: ObjectId)
GET 	/delphotos/:file/:id	controllers.FileController.deletePhoto(file: ObjectId, id: ObjectId)
Posted in MongoDB Tutorial, Play Framework Tutorial, Scala Tutorial and tagged , , , , .