web-dev-qa-db-fra.com

Téléchargement d’images dans Vapor 3 avec PostgreSQL

Je suis ce gars Martin Lasek Tutorials et maintenant je suis sur "image upload". Il semble que personne n’ait la réponse à la question "Comment télécharger des images dans Vapor 3" 

La connexion Db est ok, toutes les autres valeurs sont enregistrées.

C'est ma méthode create:

    func create(_ req: Request) throws -> Future<Response> {

    return try req.content.decode(Question.self).flatMap { question in
        return question.save(on: req).map { _ in

            return req.redirect(to: "/form")
        }
    }
}

et modèle:

final class Question: PostgreSQLModel {

var id: Int?
var questionText: String
var answers: [String]
var theme: String?
var imageName: String?
var imageData: File?

init(id: Int? = nil, questionText: String, answers: [String], theme: String, imageName: String?, imageData: File?) {

    self.id = id
    self.questionText = questionText
    self.answers = answers
    self.theme = theme
    self.imageName = imageName
    self.imageData = imageData
}

}

et modèle de feuille:

<form action="/save" method="POST" enctype="multipart/form-data" id="upload-form">
<input type="file" accept="image/png,image/jpg" name="image">
<input class="btn btn-success btn-block" type="submit" value="Legg til">
</form>

Je sais qu'une méthode de gestion de fichiers est nécessaire et les octets d'image brute à,

Mais comment puis-je y arriver?

10
Krister Moen

Ceci utilise le décodage automatique de la forme en plusieurs parties:

router.get("upload") {
    request -> Future<View> in
    return try request.view().render("upload")
}

struct ExampleUpload: Content {
    let document: File
}

// this saves the file into a Question
router.post(ExampleUpload.self, at:"upload") {
    request, upload -> Future<HTTPResponseStatus> in
    let question = try Question()
    question.imageData = upload.document.data
    question.imageName = upload.document.filename
    return question.save(on:request).transform(to: HTTPResponseStatus.ok)
}

Le fichier upload.leaf est:

<form method="POST" enctype="multipart/form-data">
<input type="file" name="document" />
<input type="submit" value="Send" />
</form>

L'utilisation du type File permet d'accéder au nom de fichier local du fichier téléchargé ainsi qu'aux données du fichier. Si vous ajoutez le reste des champs Question à la structure ExampleUpload, vous pouvez utiliser la route pour capturer tous les champs du formulaire.

5
Nick

Pour que req.content.decode(Question.self) puisse fonctionner, votre modèle doit être conforme au protocole Content, qui est l'encapsulation Vapor de Codable + d'autres éléments d'encodage/décodage.

L'avez-vous ajouté à votre modèle Question?

quelque chose comme ca:

extension Question: Content {}
2
Frederic Ruaudel

J'ai réussi à obtenir les données d'image en procédant comme suit:

struct ImageRequest: Content {
    var imageData: Data
}

func analyizeImage(_ request: Request) throws -> Future<Response> {
    return try request.content.decode(ImageRequest.self).flatMap(to: Response.self, { [weak self] imageRequest in
        guard let image = NSImage(data: imageRequest.imageData) else {
            throw Abort(.badRequest)
        }

        // Do what you want with your image
    })
}

Ma forme ressemblait à ceci:

<form method="POST" enctype="multipart/form-data">
    <input type="file" name="imageData" />
    <input type="submit" value="Send" />
</form>
2
Mihai Fratu