Получить изображение из тела ответа HTTP - PullRequest
0 голосов
/ 30 сентября 2019

Я пытаюсь получить изображение с сервера с помощью HTTP-запроса GET в моей службе клиентов. Я воспроизвел свой сценарий использования в следующем коде:

main.go:

package main

import (
    "net/http"
    "os"

    "github.com/gorilla/mux"
    log "github.com/sirupsen/logrus"
)

func main() {
    log.SetFormatter(&log.TextFormatter{})

    // Initialize router
    router := mux.NewRouter()

    args := os.Args

    if args[1] == "client" {
        log.Print("Run Client, listening on port 8080")
        router.Methods("GET").Path("/image").HandlerFunc(ClientGetImage)
        log.Fatal(http.ListenAndServe(":8080", router))
    } else if args[1] == "server" {
        log.Print("Run Server, listening on port 4242")
        router.Methods("GET").Path("/image").HandlerFunc(ServerGetImage)
        log.Fatal(http.ListenAndServe(":4242", router))
    } else {
        log.Fatal("Wrong command. Choose [client] or [server] option")
    }
}

client.go:

package main

import (
    "image"
    "log"
    "net/http"
)

func ClientGetImage(w http.ResponseWriter, r *http.Request) {
    // Make HTTP Get request to retrieve the image from the server
    log.Print("Requesting image to server")
    resp, err := http.Get("http://localhost:4242/image")

    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    m, _, err := image.Decode(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    log.Print("Pixels: ", m)
}

server.go:

package main

import (
    "bytes"
    "image"
    "image/color"
    "image/jpeg"
    "log"
    "net/http"
    "strconv"
)

func ServerGetImage(w http.ResponseWriter, r *http.Request) {
    img := image.NewGray16(image.Rect(0, 0, 1, 1))
    img.SetGray16(0, 0, color.Gray16{Y: 42000})

    // Print created
    log.Print("Pixels: ", img)

    buffer := new(bytes.Buffer)
    if err := jpeg.Encode(buffer, img, nil); err != nil {
        log.Println("unable to encode image.")
    }

    w.Header().Set("Content-Type", "image/jpeg")
    w.Header().Set("Content-Length", strconv.Itoa(len(buffer.Bytes())))
    if _, err := w.Write(buffer.Bytes()); err != nil {
        log.Println("unable to write image.")
    }
}

Цель довольно проста: после получения запроса GET клиент отправляет запрос GET на сервер для получения изображения. При получении запроса GET Клиента сервер создает изображение 1x1, закодированное в 16 бит.

После запуска моего клиента и сервера, когда я отправляю свой запрос GET клиенту, я получаю следующие журналы:

Журналы сервера:

INFO[0000] Run Server, listening on port 4242           
2019/09/30 15:32:05 Pixels: &{[164 16] 2 (0,0)-(1,1)}

Журналы клиента:

INFO[0000] Run Client, listening on port 8080           
2019/09/30 15:41:52 Requesting image to server
2019/09/30 15:41:52 Pixels: &{[164 164 164 164 164 164 164 164 164 164 164 164 164 164 164
 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 1
64 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164
 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 1
64 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164
 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 1
64 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164
 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 1
64 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164
 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 1
64 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164
 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164 164] [128 128 128 128 128 128
 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 1
28 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128
 128 128 128 128 128 128 128 128 128 128 128 128 128] [128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128] 16 8 YCbCrSubsampleRatio420 (0,0)-(1,1)}

Я ожидал, что клиент напечатает: Pixels: & {[164 16] 2 (0,0) - (1,1)}. Это просто разница в формате печати или изображение неправильно декодировано?

1 Ответ

0 голосов
/ 01 октября 2019

Спасибо, Cerise Limon, я не знал, что декодированное изображение было YCbCr. Если я пытаюсь преобразовать изображение в Gray16, оно дает мне ожидаемый формат вывода. Намного понятнее!

На самом деле это не было связано с HTTP. Я написал более простой фрагмент кода:


    // Create a 2x1 Gray16 image
    img := image.NewGray16(image.Rect(0, 0, 2, 1))
    // Set 1st pixel to 42
    img.SetGray16(0, 0, color.Gray16{Y: 42})

    log.Print("Pixels: ", img)

    // Encode the image
    buffer := new(bytes.Buffer)
    jpeg.Encode(buffer, img, &jpeg.Options{Quality: 100})

    // Decode the encoded buffer
    m, _ := jpeg.Decode(buffer)

    // Create a Gray16 image and fill it with decoded image
    newImage := image.NewGray16(image.Rect(0, 0, m.Bounds().Dx(), m.Bounds().Dy()))
    draw.Draw(newImage, newImage.Bounds(), m, m.Bounds().Min, draw.Src)

    log.Print("Pixels: ", newImage)

Это дает мне следующий вывод:

INFO[0000] Pixels: &{[0 42 0 0] 4 (0,0)-(2,1)}          
INFO[0000] Pixels: &{[0 0 0 0] 4 (0,0)-(2,1)}

Обратите внимание, что если я заменю Gray16 на Gray, кодирование / декодирование будет работать правильно: на выходе получается то же изображение, что и на входе.

Я что-то здесь упустил? Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...