Created
March 13, 2019 11:09
-
-
Save paulm17/4bd17334660101139a973921924a00b3 to your computer and use it in GitHub Desktop.
error transforming image, Framebuffer contains no pixels
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io/ioutil" | |
"math" | |
"os" | |
"path/filepath" | |
"strings" | |
"github.com/discordapp/lilliput" | |
) | |
type context struct { | |
PayloadData payloadData | |
Decoder lilliput.Decoder | |
ImageHeader *lilliput.ImageHeader | |
Dir string | |
} | |
type payloadData struct { | |
FileID string | |
Filename string | |
Extension string | |
} | |
// EncodeOptions image sizes | |
var EncodeOptions = map[string]map[int]int{ | |
".jpeg": map[int]int{lilliput.JpegQuality: 85}, | |
".png": map[int]int{lilliput.PngCompression: 7}, | |
".webp": map[int]int{lilliput.WebpQuality: 85}, | |
} | |
func main() { | |
p := payloadData{} | |
p.FileID = "01d5v8kqp4bqwnr33rxz7qzp6b" | |
p.Filename = "01d5v8kqp4bqwnr33rxz7qzp6b.jpeg" | |
p.Extension = "jpeg" | |
c := context{} | |
c.PayloadData = p | |
c.Dir = "./upload/dam/" | |
c.verifyImage() | |
sizes := []int{150, 600, 1024, 1600} | |
for _, size := range sizes { | |
fmt.Sprintf("processing size: %d", size) | |
err := c.resizeImage(size) | |
fmt.Println(err) | |
} | |
fmt.Println("done") | |
} | |
func (c *context) verifyImage() error { | |
// decoder wants []byte, so read the whole file into a buffer | |
inputBuf, err := ioutil.ReadFile(c.Dir + c.PayloadData.Filename) | |
if err != nil { | |
return fmt.Errorf("failed to read input file, %s", err) | |
} | |
decoder, err := lilliput.NewDecoder(inputBuf) | |
// this error reflects very basic checks, | |
// mostly just for the magic bytes of the file to match known image formats | |
if err != nil { | |
return fmt.Errorf("error decoding image, %s", err) | |
} | |
c.Decoder = decoder | |
header, err := decoder.Header() | |
// this error is much more comprehensive and reflects | |
// format errors | |
if err != nil { | |
return fmt.Errorf("error reading image header, %s", err) | |
} | |
c.ImageHeader = header | |
return nil | |
} | |
func (c *context) resizeImage(outputWidth int) error { | |
// name of output file, also determines output type | |
outputFilename := fmt.Sprintf("%d_%s.%s", outputWidth, c.PayloadData.FileID, c.PayloadData.Extension) | |
// perform stretching resize instead of cropping | |
stretch := false | |
// get ready to resize image, | |
// using 8192x8192 maximum resize buffer size | |
ops := lilliput.NewImageOps(8192) | |
defer ops.Close() | |
// create a buffer to store the output image, 50MB in this case | |
outputImg := make([]byte, 50*1024*1024) | |
// use user supplied filename to guess output type if provided | |
// otherwise don't transcode (use existing type) | |
outputType := "." + strings.ToLower(c.Decoder.Description()) | |
if outputFilename != "" { | |
outputType = filepath.Ext(outputFilename) | |
} | |
outputHeight := c.ImageHeader.Height() | |
if outputWidth == 150 { | |
// Thumbnail | |
outputHeight = 150 | |
} else if c.ImageHeader.Width() == c.ImageHeader.Height() { | |
// Image is 1:1 | |
outputHeight = outputWidth | |
} else { | |
// Resize height based on width / ratio | |
floatRatio := float64(c.ImageHeader.Width()) / float64(c.ImageHeader.Height()) | |
floatWidth := float64(outputWidth) | |
floatDivision := floatWidth / floatRatio | |
floatHeight := math.Round(floatDivision) | |
outputHeight = int(floatHeight) | |
} | |
resizeMethod := lilliput.ImageOpsFit | |
if stretch { | |
resizeMethod = lilliput.ImageOpsResize | |
} | |
if outputWidth == c.ImageHeader.Width() && outputHeight == c.ImageHeader.Height() { | |
resizeMethod = lilliput.ImageOpsNoResize | |
} | |
opts := &lilliput.ImageOptions{ | |
FileType: outputType, | |
Width: outputWidth, | |
Height: outputHeight, | |
ResizeMethod: resizeMethod, | |
NormalizeOrientation: true, | |
EncodeOptions: EncodeOptions[outputType], | |
} | |
// resize and transcode image | |
outputImg, err := ops.Transform(c.Decoder, opts, outputImg) | |
if err != nil { | |
return fmt.Errorf("error transforming image, %s", err) | |
} | |
if _, err := os.Stat(c.Dir + outputFilename); !os.IsNotExist(err) { | |
return fmt.Errorf("output filename %s exists, quitting", outputFilename) | |
} | |
err = ioutil.WriteFile(c.Dir+outputFilename, outputImg, 0400) | |
if err != nil { | |
return fmt.Errorf("error writing out resized image, %s", err) | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment