رفع وتحميل الصور، تغيير الحجم، مخزن في قاعدة البيانات، وعرض

StackOverflow https://stackoverflow.com/questions/1404814

سؤال

هل هناك مثال مختصر لكيفية تحميل صورة، حجمه، واحفظها في قاعدة البيانات ومن ثم تخدم صورة حتى باستخدام مصعد؟

وأنا متأكد من أني يمكن أن قطعة معا من تحميل الملفات، جافا 2D API، مخطط رفع واجهات برمجة التطبيقات الاستجابة. لكن هل هناك أي رمز المثال يمكنني اتباعها لتفعل ذلك "الصحيحة" أو الطريقة الموصى بها؟

هل كانت مفيدة؟

المحلول

وأنا فعلت هذا لحقل معين مرتبط S3 عن طريق إنشاء MappedField جديدة. ولدي أيضا بعض التعليمات البرمجية لتغيير، ولكن لم تختبر أو نشرها (حتى استخدام بحذر).

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

نصائح أخرى

والجواب أخرى يصف بشكل رائع كيفية تغيير حجم الصورة وتخزينها في اشارة الى الملف على نظام الملفات.

إذا كنت ترغب في استخدام مخطط رفع لتخزين محتويات الملف الفعلية، عليك أن خلق لكم كائن نموذج مخصص، وتحديد حقل ثنائي على ذلك. جرب شيئا من هذا القبيل:

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



}
}

وبعد ذلك، في الصف التمهيد، إضافة هذا Document في النهاية:

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

وفويلا. باستخدام Document save (new Document) يخزن ذلك إلى قاعدة البيانات. يمكن تعيين الحقول A new Document باستخدام طريقة set. محاولة اللعب مع delete_!، find وأساليب findAll من المفرد Document حذف أو العثور عليه في قاعدة البيانات. يجب أن تكون واضحة من هذه النقطة.

وأخيرا، لعرض الصور، يمكنك تجاوز قواعد إيفاد رفع ل(في الصف التمهيد، 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)
}

واستنادا إلى إجابة مقبولة من قبل جون هوفمان، أنا ثابت البق. روايته عبث تصل نسبة الارتفاع (دائما يصبح 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
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top