我正在使用Play Framework和ReactiveMongo DB来存储GridFS中的上传文件。这是代码:
def saveAttachment(id: String) = Action.async(gridFSBodyParser(gridFS)) { request =>
// here is the future file!
val futureFile = request.body.files.head.ref
// when the upload is complete, we add the article id to the file entry (in order to find the attachments of the article)
val futureUpdate = for {
file <- futureFile
// here, the file is completely uploaded, so it is time to update the user
updateResult <- {
gridFS.files.update(
BSONDocument("_id" -> file.id),
BSONDocument("$set" -> BSONDocument("user" -> BSONObjectID(id)),
"$set" -> BSONDocument("size" -> "original")))
}
} yield updateResult
futureUpdate.map {
case _ => Ok("xx")
}.recover {
case e => InternalServerError(e.getMessage())
}
}
如何使用属性&#34; size&#34;添加另一个文件? - &GT; &#34;拇指&#34;使用相同的上传图片,但重新调整为小拇指? 我这里有两个问题:
感谢您的回答。这是一个很好的方向。我正在寻找GridFS的解决方案。以下是我最终的结果:
def saveAttachment(id: String) = Action.async(gridFSBodyParser(gridFS)) { request =>
// here is the future file!
val futureFile = request.body.files.head.ref
// when the upload is complete, we add the article id to the file entry (in order to find the attachments of the article)
val futureUpdate = for {
file <- futureFile
// here, the file is completely uploaded, so it is time to update the user
updateResult <- {
gridFS.files.update(
BSONDocument("_id" -> file.id),
BSONDocument("$set" -> BSONDocument("metadata" ->
BSONDocument("user" -> BSONObjectID(id),
"size" -> "original"))))
val iterator = gridFS.enumerate(file).run(Iteratee.consume[Array[Byte]]())
iterator.flatMap {
bytes => {
// Create resized image
val enumerator: Enumerator[Array[Byte]] = Enumerator.outputStream(
out => {
Image(bytes).bound(120, 120).writer(Format.JPEG).withCompression(90).write(out)
}
)
val data = DefaultFileToSave(
filename = file.filename,
contentType = file.contentType,
uploadDate = Some(DateTime.now().getMillis),
metadata = file.metadata ++ BSONDocument(
"user" -> BSONObjectID(id),
"size" -> "thumb"
)
)
Logger.warn(s"Saving resized image: [id=$id, metadata=${data.metadata}}]")
gridFS.save(enumerator, data).map {
image => Some(image)
}
}
}
}
} yield updateResult
futureUpdate.map {
case _ => Ok("xx")
}.recover {
case e => InternalServerError(e.getMessage())
}
}
答案 0 :(得分:2)
解决方案非常简单,我使用scrimage进行图像处理,这是我的控制器:
// 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")
}
}
}
}
请注意调整大小部分。
您可以解决的第一个问题,例如,只需复制基础文件并使用调整大小的副本进行第二次save
调用。我手边的代码没有完整的解决方案,如果您需要进一步的帮助,请随时询问详细信息。