How to Respond with an Image Using Vapor

How to respond with an image using Vapor?

Two additional approaches:

  1. A route using Leaf to deploy the image:

    route.get("/my/random/route") {
    request -> Future<View> in
    return try request.view().render("image", ["imgname":"image.png"])
    }

With image.leaf containing:

<img src="#(imgname)">

  1. A re-direct to the original location in Public:

    route.get("/my/random/route") {
    request -> Response in
    return request.redirect(to: "/image.png")
    }

Swift Vapor 4 Leaf Image not displayed in view on run

As Nick said it was a speeling mistake .

I wrote „scr“, but it must be „src“
Correct:

<img src="https://www.w3schools.com/tags/img_girl.jpg" alt="test image" width="500" height="600">

How to use vapor for uploading/downloading image?

The uploaded image will be one part of a multi-part request, so you need to use just the part that contains the image. .bytes will give you the whole request. I use:

guard let fileBytes = info.formData?["photo"]?.part.body

Or

guard let fileBytes = info?["photo"]?.part.body

if you aren't using a form.

Swift - Vapor Using HTML

You can build your own Response, avoiding views completely.

drop.get { req in
return Response(status: .ok, headers: ["Content-Type": "text/html"], body: "<html><img src=http://www.w3schools.com/html/pic_mountain.jpg></html>")
}

or

drop.get { req in
let response = Response(status: .ok, body: "<html><img src=http://www.w3schools.com/html/pic_mountain.jpg></html>")
response.headers["Content-Type"] = "text/html"
return response
}

Image Upload in Vapor 3 using PostgreSQL

This uses automatic decoding of the multi-part form:

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

The upload.leaf file is:

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

Using the type File enables the local filename of the uploaded file to be accessed as well as the file data. If you add in the rest of the Question fields to the ExampleUpload structure, you can use the route to capture the whole form's fields.

How to handle multiple images upload in vapor 4?

By standard for multiple files name should contain []

Try this form

<form method="POST" action="/create" enctype="multipart/form-data">
<div class="mb-3">
<label for="imgs">Images</label>
<input type="file" accept="image/*" name="imgs[]" id="imgs" multiple/>
</div>
</form>

and then in Vapor

struct Request: Content {
let imgs: [File] //or [Data]
}

Swift Vapor 4 upload , validate , resize an image file

After Two Days of Testing, I am able to do that using SwiftGD, So I came up with this .. hope it is useful.

Image Validation

// Do not forget to decode the image to File type Not Data type
let img = team.img

if img.data.readableBytes > 1000000 {
errors.append( "error ... image size should not exceed 1 mb")
}

if !["png", "jpeg", "jpg"].contains(img.extension?.lowercased()) {
errors.append("extension is not acceptable")
}

let imageNewNameAndExtension = "\(UUID())"+".\(img.extension!.lowercased())"

The upload an resize part

// The upload Path
let path = req.application.directory.publicDirectory + "uploads/" + imageNewNameAndExtension
// The path to save the resized img
let newPath = req.application.directory.publicDirectory + "uploads/teams/" + imageNewNameAndExtension

// SwiftNIO File handle
let handle = try await req.application.fileio.openFile(path: path,mode: .write,flags:.allowFileCreation(posixMode:0x744),eventLoop: req.eventLoop).get()

// Save the file to the server
req.application.fileio.write(fileHandle:handle,buffer:img.data,eventLoop: req.eventLoop).whenSuccess { _ in
// SwiftGD part to resize the image
let url = URL(fileURLWithPath: path)
let newUrl = URL(fileURLWithPath: newPath)
let image = Image(url: url)
if let im = image {
if let mg = im.resizedTo(width: 250, height: 250){
mg.write(to: newUrl)
}
}

try? handle.close()
}


Related Topics



Leave a reply



Submit