Frage

Gibt es ein prägnantes Beispiel dafür, wie ein Bild hochladen, Größe ändern, sollte sie in einer Datenbank und dann das Bild dient Aushebung mit?

Ich bin sicher, dass ich es zusammen aus der Datei-Upload-piece könnte, Java 2D-API, Lift Mapper und Response-APIs. Aber gibt es einen Beispielcode ich folgen kann, es zu tun, um den ‚richtigen‘ oder empfohlene Weg?

War es hilfreich?

Lösung

Ich tat dies für ein Mapper Feld durch die Schaffung eines neuen MappedField bis s3 verbunden. Ich habe auch einen etwas Code, um die Größe, aber noch nicht getestet oder eingesetzt (so mit Vorsicht verwenden).

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
        }
    }
}

Andere Tipps

Die andere Antwort beschreibt schön, wie die Größe des Bildes und einen Verweis auf die Datei auf dem Dateisystem gespeichert werden.

Wenn Sie den Lift-Mapper zum Speichern der tatsächlichen Dateiinhalte verwenden möchten, müssen Sie Ihr eigenes Model-Objekt erstellen, und definieren auf sie ein binäres Feld. Probieren Sie etwas wie folgt aus:

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
  }
}



}
}

Dann in Bootstrap-Klasse, fügen Sie diese Document am Ende:

Schemifier.schemify(true, Schemifier.infoF _, User, Document)

Voila. Mit Document save (new Document) speichert sie in der Datenbank. Ein Feld des new Document kann mit dem set Verfahren eingestellt werden. Versuchen Sie, mit delete_! spielen, find, findAll Methoden des Document Singleton zu löschen oder in der Datenbank zu finden. Es soll von diesem Punkt an unkompliziert sein.

Schließlich das Bild anzuzeigen, können Sie Lift Zuteilungsregeln (in Bootstrap-Klasse, Boot.scala) außer Kraft setzen. Versuchen Sie, mit diesem Beispiel spielen um die die Regeln für pdf-Anfragen hat Vorrang vor:

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)
}

Auf der Grundlage der akzeptierten Antwort von Jon Hoffman, befestigte ich die Bugs. Seine Version verunstaltet das Seitenverhältnis (es immer wird 1: 1), weil die Mathematik war weg in ein paar Flecken. Diese Version passt die Größe große Bilder, bis sie passen, und achtet das Seitenverhältnis.

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
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top