画像をアップロードし、サイズを変更し、データベースに保存し、Liftを使用して画像を提供する方法の簡潔な例がありますか?イメージをアップロード、サイズ変更、データベースに保存、表示
ファイルアップロード、Java 2D API、リフトマッパー、レスポンスAPIからまとめてもいいと思います。しかし、私が「正しい」方法や推奨する方法を実行するための例コードはありますか?
画像をアップロードし、サイズを変更し、データベースに保存し、Liftを使用して画像を提供する方法の簡潔な例がありますか?イメージをアップロード、サイズ変更、データベースに保存、表示
ファイルアップロード、Java 2D API、リフトマッパー、レスポンスAPIからまとめてもいいと思います。しかし、私が「正しい」方法や推奨する方法を実行するための例コードはありますか?
新しいMappedFieldを作成して、s3にリンクされたMapperフィールドでこれを行いました。サイズを変更するコードもありますが、テストやデプロイはしていません(注意して使用してください)。
class MappedS3Image[T<:Mapper[T]](owner: T, val path:String, maxWidth: String, maxHeight:String) extends MappedString[T](owner, 36) {
def url:String = MappedS3Image.fullImgPath(path, is)
def setFromUpload(fileHolder: Box[FileParamHolder]) = {
S3Sender.uploadImageToS3(path, fileHolder).map(this.set(_))
}
override def asHtml:Node = <img src={url} style={"max-width:" + maxWidth + ";max-height:"+maxHeight} />
override def _toForm: Box[Elem] = Full(SHtml.fileUpload(fu=>setFromUpload(Full(fu))))
}
import java.awt.Image
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
import java.awt.Graphics2D
import java.awt.AlphaComposite
object ImageResizer {
def resize(is:java.io.InputStream, maxWidth:Int, maxHeight:Int):BufferedImage = {
val originalImage:BufferedImage = ImageIO.read(is)
val height = originalImage.getHeight
val width = originalImage.getWidth
if (width <= maxWidth && height <= maxHeight)
originalImage
else {
var scaledWidth:Int = width
var scaledHeight:Int = height
val ratio:Double = width/height
if (scaledWidth > maxWidth){
scaledWidth = maxWidth
scaledHeight = (scaledWidth.doubleValue/ratio).intValue
}
if (scaledHeight > maxHeight){
scaledHeight = maxHeight
scaledWidth = (scaledHeight.doubleValue*ratio).intValue
}
val scaledBI = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB)
val g = scaledBI.createGraphics
g.setComposite(AlphaComposite.Src)
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose
scaledBI
}
}
}
欠陥のある数学。これは、幅/高さ比を混乱させる。私は固定版(3年後)で答えました。それでも、私に使ってもらうための正しいライブラリに関する質問に答えてくれてとても役に立ちました。 –
私は以下の訂正された回答を追加しました。 –
イメージのサイズを変更し、ファイルへの参照をファイルシステムに保存する方法については、もう1つの回答で詳しく説明しています。
リフトマッパーを使用して実際のファイルの内容を保存する場合は、カスタムモデルオブジェクトを作成し、その上にバイナリフィールドを定義する必要があります。最後に、このDocument
を追加し、ブートストラップクラスで、その後
package code {
package model {
import _root_.net.liftweb.mapper._
import _root_.net.liftweb.util._
import _root_.net.liftweb.common._
// singleton object which manipulates storing of Document instances
object Document extends Document with KeyedMetaMapper[Long, Document] {
}
class Document extends KeyedMapper[Long, Document] {
def getSingleton = Document
def primaryKeyField = id
object id extends MappedLongIndex(this)
object name extends MappedString(this, 20) {
override def displayName = "Name"
override def writePermission_? = true
}
object content extends MappedBinary(this) {
override def displayName = "Content"
override def writePermission_? = true
}
}
}
}
:このような何かを試してみてください
Schemifier.schemify(true, Schemifier.infoF _, User, Document)
出来上がり。 Document save (new Document)
を使用すると、データベースに格納されます。 set
メソッドを使用して、new Document
のフィールドを設定することができます。 delete_!
、find
、findAll
シングルトンの方法を試してみてください。削除するか、データベースで見つけてください。Document
この時点から、それは簡単であるはずです。
最後に、イメージを表示するために、Liftのディスパッチルール(ブートストラップクラスBoot.scala)をオーバーライドできます。
def getFile(filename: String): Option[Document] = {
val alldocs = Document.findAll()
alldocs.find(_.name.get == filename)
}
LiftRules.statelessDispatchTable.append {
case Req("file" :: name :: Nil, "pdf", GetRequest) =>
() =>
println("Got request for: " + name + ".pdf")
for {
stream <- tryo(
getFile(name + ".pdf") map {
doc => new java.io.ByteArrayInputStream(doc.content.get)
} getOrElse null
)
if null ne stream
} yield StreamingResponse(stream,
() => stream.close,
stream.available,
List("Content-Type" -> "application/pdf"),
Nil,
200)
}
Jon Hoffmanの回答に基づいて、私はバグを修正しました。数学的には数少ないため、アスペクト比は常に1:1になります。このバージョンは、フィットするまで大きな画像のサイズを変更し、アスペクト比を尊重します。
def resize(is:java.io.InputStream, maxWidth:Int, maxHeight:Int):BufferedImage = {
require (maxWidth > 0)
require (maxHeight > 0)
val originalImage:BufferedImage = ImageIO.read(is)
var height = originalImage.getHeight
var width = originalImage.getWidth
// Shortcut to save a pointless reprocessing in case the image is small enough already
if (width <= maxWidth && height <= maxHeight)
originalImage
else {
// If the picture was too big, it will either fit by width or height.
// This essentially resizes the dimensions twice, until it fits
if (width > maxWidth){
height = (height.doubleValue() * (maxWidth.doubleValue()/width.doubleValue())).intValue
width = maxWidth
}
if (height > maxHeight){
width = (width.doubleValue() * (maxHeight.doubleValue()/height.doubleValue())).intValue
height = maxHeight
}
val scaledBI = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
val g = scaledBI.createGraphics
g.setComposite(AlphaComposite.Src)
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose
scaledBI
}
}
嫌なことはありませんが、これはまともなプロジェクトのようです。それには陰謀、冒険、SQLなどすべてがあります。 –
うん、私は行くつもりだった!私はちょうど私が始める前に助言を求めると思った。 – Joe