The solution is quite straightforward, I use scrimage for image processing, and here's my controller:
// imports omitted
def upload = Authenticated.async(parse.multipartFormData) { request =>
// some plumbing omitted
request.body.file("photo") match {
// validations omitted
case Some(photo) =>
val fileToSave = DefaultFileToSave(photo.filename, photo.contentType)
val resizedFile = Image(photo.ref.file).fitToWidth(120).write
val enumerator = Enumerator(resizedFile)
gfs.save(enumerator, fileToSave) map {
case file =>
val id = file.id.asInstanceOf[BSONObjectID].stringify
Ok(obj("files" -> Seq(obj(
"id" -> id,
"name" -> file.filename,
"size" -> file.length,
"url" -> routes.Photos.photo(id).url,
"thumbnailUrl" -> routes.Photos.photo(id).url,
"deleteUrl" -> "",
"deleteType" -> "DELETE"
))))
} recover {
case e =>
Logger.error(e.toString)
InternalServerError("upload failed")
}
}
}
}
Please note the resizing part.
The first problem you can solve for example by simply copying underlying file and making a second save
call with a resized copy. I don't have a complete solution in code at hand, so feel free to ask for details if you'll need further help.