package main
import (
"fmt"
"image"
_ "image/jpeg"
_ "image/png"
"io"
"log"
"os"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
// Send an image to microservice for image analysis
func ImageRequestHandler(c echo.Context, img *os.File) error {
// TODO: Use user image instead
// Get filesize of image
stat, err := img.Stat()
log.
Print("File size: ", stat.
Size()/1024, " kb")
// Get width and height in px for the image
im, _, err := image.DecodeConfig(img)
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", img.Name(), err)
}
// Form JSON response that contains name, size, height and width
jsonStr := fmt.Sprintf(`{ "name": "%s",
"size": %d,
"width": %d,
"height": %d
}`, img.Name(), stat.Size(), im.Width, im.Height)
c.Response().Header().Set("Content-Type", "application/json")
//TODO: Avoid double casting []byte string?!
c.Response().Write([]byte(string(jsonStr)))
// TODO: Figure out how to avoid return and just return with c.Response() similar to w.Write
return err
}
func main() {
e := echo.New()
// Avoid CORS error when testing with redocly
e.Use(middleware.CORS())
// API Versioning
apiGroup := e.Group("/api")
apiv1Group := apiGroup.Group("/v1")
apiv1Group.POST("/imageanalysis", func(c echo.Context) error {
// TODO: Catch error when no file is send in POST Request
// Source
file, err := c.FormFile("file")
if err != nil {
return err
}
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()
// Destination
dst, err := os.Create(file.Filename)
if err != nil {
return err
}
defer dst.Close()
// Copy
if _, err = io.Copy(dst, src); err != nil {
return err
}
// TODO: Why do i need to open the file here again, instead of just passing the reference from os.Create()?
// TODO: Maybe don't create the file on disk at all, just send it from memory
buf, err := os.Open(dst.Name())
if err != nil {
}
defer buf.Close()
return ImageRequestHandler(c, buf)
})
e.Logger.Fatal(e.Start(":1324"))
}
cGFja2FnZSBtYWluCgppbXBvcnQgKAoJImZtdCIKCSJpbWFnZSIKCV8gImltYWdlL2pwZWciCglfICJpbWFnZS9wbmciCgkiaW8iCgkibG9nIgoJIm9zIgoKCSJnaXRodWIuY29tL2xhYnN0YWNrL2VjaG8vdjQiCgkiZ2l0aHViLmNvbS9sYWJzdGFjay9lY2hvL3Y0L21pZGRsZXdhcmUiCikKCi8vIFNlbmQgYW4gaW1hZ2UgdG8gbWljcm9zZXJ2aWNlIGZvciBpbWFnZSBhbmFseXNpcwpmdW5jIEltYWdlUmVxdWVzdEhhbmRsZXIoYyBlY2hvLkNvbnRleHQsIGltZyAqb3MuRmlsZSkgZXJyb3IgewoJLy8gVE9ETzogVXNlIHVzZXIgaW1hZ2UgaW5zdGVhZAoJbG9nLlByaW50KGltZy5OYW1lKCkpCgoJLy8gR2V0IGZpbGVzaXplIG9mIGltYWdlCglzdGF0LCBlcnIgOj0gaW1nLlN0YXQoKQoJbG9nLlByaW50KCJGaWxlIHNpemU6ICIsIHN0YXQuU2l6ZSgpLzEwMjQsICIga2IiKQoKCS8vIEdldCB3aWR0aCBhbmQgaGVpZ2h0IGluIHB4IGZvciB0aGUgaW1hZ2UKCWltLCBfLCBlcnIgOj0gaW1hZ2UuRGVjb2RlQ29uZmlnKGltZykKCWlmIGVyciAhPSBuaWwgewoJCWZtdC5GcHJpbnRmKG9zLlN0ZGVyciwgIiVzOiAldlxuIiwgaW1nLk5hbWUoKSwgZXJyKQoJfQoJbG9nLlByaW50KGltLldpZHRoKQoKCS8vIEZvcm0gSlNPTiByZXNwb25zZSB0aGF0IGNvbnRhaW5zIG5hbWUsIHNpemUsIGhlaWdodCBhbmQgd2lkdGgKCWpzb25TdHIgOj0gZm10LlNwcmludGYoYHsgIm5hbWUiOiAiJXMiLAoJCQkJICJzaXplIjogJWQsCgkJCQkgIndpZHRoIjogJWQsCgkJCQkgImhlaWdodCI6ICVkCgkJCQl9YCwgaW1nLk5hbWUoKSwgc3RhdC5TaXplKCksIGltLldpZHRoLCBpbS5IZWlnaHQpCglsb2cuUHJpbnQoanNvblN0cikKCgljLlJlc3BvbnNlKCkuSGVhZGVyKCkuU2V0KCJDb250ZW50LVR5cGUiLCAiYXBwbGljYXRpb24vanNvbiIpCgkvL1RPRE86IEF2b2lkIGRvdWJsZSBjYXN0aW5nIFtdYnl0ZSBzdHJpbmc/IQoJYy5SZXNwb25zZSgpLldyaXRlKFtdYnl0ZShzdHJpbmcoanNvblN0cikpKQoKCS8vIFRPRE86IEZpZ3VyZSBvdXQgaG93IHRvIGF2b2lkIHJldHVybiBhbmQganVzdCByZXR1cm4gd2l0aCBjLlJlc3BvbnNlKCkgc2ltaWxhciB0byB3LldyaXRlCglyZXR1cm4gZXJyCn0KCmZ1bmMgbWFpbigpIHsKCWUgOj0gZWNoby5OZXcoKQoKCS8vIEF2b2lkIENPUlMgZXJyb3Igd2hlbiB0ZXN0aW5nIHdpdGggcmVkb2NseQoJZS5Vc2UobWlkZGxld2FyZS5DT1JTKCkpCgoJLy8gQVBJIFZlcnNpb25pbmcKCWFwaUdyb3VwIDo9IGUuR3JvdXAoIi9hcGkiKQoJYXBpdjFHcm91cCA6PSBhcGlHcm91cC5Hcm91cCgiL3YxIikKCglhcGl2MUdyb3VwLlBPU1QoIi9pbWFnZWFuYWx5c2lzIiwgZnVuYyhjIGVjaG8uQ29udGV4dCkgZXJyb3IgewoJCS8vIFRPRE86IENhdGNoIGVycm9yIHdoZW4gbm8gZmlsZSBpcyBzZW5kIGluIFBPU1QgUmVxdWVzdAoJCS8vIFNvdXJjZQoJCWZpbGUsIGVyciA6PSBjLkZvcm1GaWxlKCJmaWxlIikKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCQlzcmMsIGVyciA6PSBmaWxlLk9wZW4oKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJCWRlZmVyIHNyYy5DbG9zZSgpCgoJCS8vIERlc3RpbmF0aW9uCgkJZHN0LCBlcnIgOj0gb3MuQ3JlYXRlKGZpbGUuRmlsZW5hbWUpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9CgkJZGVmZXIgZHN0LkNsb3NlKCkKCgkJLy8gQ29weQoJCWlmIF8sIGVyciA9IGlvLkNvcHkoZHN0LCBzcmMpOyBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCQkvLyBUT0RPOiBXaHkgZG8gaSBuZWVkIHRvIG9wZW4gdGhlIGZpbGUgaGVyZSBhZ2FpbiwgaW5zdGVhZCBvZiBqdXN0IHBhc3NpbmcgdGhlIHJlZmVyZW5jZSBmcm9tIG9zLkNyZWF0ZSgpPwoJCS8vIFRPRE86IE1heWJlIGRvbid0IGNyZWF0ZSB0aGUgZmlsZSBvbiBkaXNrIGF0IGFsbCwganVzdCBzZW5kIGl0IGZyb20gbWVtb3J5CgkJYnVmLCBlcnIgOj0gb3MuT3Blbihkc3QuTmFtZSgpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlsb2cuRmF0YWwoZXJyKQoJCX0KCQlkZWZlciBidWYuQ2xvc2UoKQoKCQlyZXR1cm4gSW1hZ2VSZXF1ZXN0SGFuZGxlcihjLCBidWYpCgl9KQoJZS5Mb2dnZXIuRmF0YWwoZS5TdGFydCgiOjEzMjQiKSkKfQo=