2017-05-01 2 views
1

Ich würde wahrscheinlich pressly/chi bevorzugen, aber ich denke, es macht keinen Unterschied. I imagine einen Eingang URL wie diese example.com/Jd8saD.jpg?resize=420x320&fit=crop&rotate=90 gegeben, dann wäre es wegen r.Get("/:image", ImageGET) auf die folgende GET-Funktion gehen:Prozessbild bei mehreren URL-Parametern in Go

function ImageGET(w http.ResponseWriter, r *http.Request) { 
    if r.URL.Query().Get("resize") != "" { 
    // do something 
    } 
    if r.URL.Query().Get("crop") != "" { 
    // do something 
    } 
    if r.URL.Query().Get("watermark") != "" { 
    // do something 
    } 
    etc 
} 

Nun, meine Frage ist, wie soll ich entwerfen, was Funktion, um die Bildverarbeitung funktioniert, so dass es alles richtig und effizient verarbeiten? Ich erwarte nicht, dass Sie Code schreiben, der die Größenänderung übernimmt, aber wie würden diese Funktionen aussehen? Vielleicht:

function Resize(size string) (imgfile?, error) { 
    // the resize stuff 
} 

Was wäre das imgfile zurückgegeben werden? Eine Struktur mit einigen relevanten IMG-Informationen?

Antwort

1

Wahrscheinlich

imgfile

wird erfüllen die image.Image Schnittstelle und nicht die auf der Festplatte gespeicherten Daten (dh. Die tatsächliche jpg-Datei)

Bild ist ein endliches rechteckiges Gitter der Farbe. Farbwerte, die von einem Farbenmodell genommen werden.

Viele Drittanbieter-Golang-Bildbibliotheken verwenden image.Image, um Bilder zu manipulieren.


I würde eine Standard-Schnittstelle verwendet image.Image abgerufen (zum Lese-Speicher) von einem Dateinamen in der imageGET Funktion und modifiziere, um die Abfragen nach. Sie können auch die jpeg Golang-Bibliothek von der Standardbibliothek aus sehen.

function ImageGET(w http.ResponseWriter, r *http.Request) { 
    // GetJPEGImageFromFileSystem must decode os.File content and 
    // return a golang image.Image interface 
    img, _ := GetJPEGImageFromFileSystem(r.URL.Query().Get("filename")) 
    if r.URL.Query().Get("resize") != "" { 
     // If resizing, write over the image.Image in Memory, 
     // but not the image File on disk 
     img, _ = Resize(img, r.URL.Query().GET("resize")) 
    } 
    // etc... 
} 

function Resize(img image.Image, size string) (image.Image, error) { 
    // the resize stuff -- or, alternatively just call a dependency in the original handler to resize 
    return resizedImage, nil 
} 
+0

Das ist wirklich großartig, ich wundere mich .. mit diesem Ansatz werde ich wahrscheinlich am Ende die Bildbearbeitung Bibliothek (z. B. libvips) immer und immer wieder mit jedem Parameter aufrufen. Würdest du es auch so machen, oder wäre es vielleicht schlauer, die Parameter zu speichern und dann die Bildbearbeitung in einer Process-Funktion vorzunehmen, oder vielleicht noch etwas anderes? – fisker

+0

Mmh, ich bin mir nicht sicher, wie libvips funktioniert, aber ich wette, es wäre viel einfacher, eine Prozessfunktion zu haben, in der die Abfragen übergeben werden könnten – Nevermore

+0

Sie können libvips in beide Richtungen verwenden. Sie können die Grundfunktionen einzeln aufrufen, oder Sie können eine einzelne High-Level-Thumbnail-Funktion mit einer Reihe von Parametern aufrufen. Wenn Sie Ihre Parameter zusammentragen und vips_thumbnail() am Ende aufrufen, können Sie sicher sein, dass die grundlegenden Funktionen für Sie in der besten Reihenfolge aufgerufen werden. API hier: http://jcupitt.github.io/libvips/API/current/libvips-resample.html#vips-thumbnail Intro zur Größenanpassung hier: https://github.com/jcupitt/libvips/wiki/HOWTO-- --Image-Schrumpf Intro zu viphumbnail hier: http://jcupitt.github.io/libvips/API/current/Using-vipsthumbnail.md.html – user894763

1

Nun, meine Frage ist, wie soll ich entwerfen, was Funktion funktioniert die Bildverarbeitung, so dass sie alles richtig verarbeiten und effizient?

Abhängig von dem Paket, das Sie für Ihre Sachen verwenden und was Sie damit machen wollen. Wenn Sie zum Beispiel auf die imaging package schauen Sie sehen, dass sie immer zurück: *image.NRGBA

Dieser Typ implementiert die image.Image Schnittstelle. Im nächsten Schritt können Sie Encode function verwenden.

func Encode (w io.Writer, img image.Image, Format Format) Fehler

Wie Sie sehen, dass Funktion ein io.Writer verwendet.

function ImageGET(w http.ResponseWriter, r *http.Request) { 
    // ... 
    imaging.Encode(w,img,imaging.PNG) 
    // ... 

So müssen Sie nur den Schreiber von Ihrem Handler dort und fertig verwenden.

Um Ihre Funktion korrekt zu halten, geben Sie einfach die image.Image Schnittstelle zurück.