fix jpeg
This commit is contained in:
@@ -5,18 +5,19 @@ package capture
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
ljpeg "github.com/pixiv/go-libjpeg/jpeg"
|
||||
)
|
||||
|
||||
func encodeJPEG(img image.Image, quality int) ([]byte, error) {
|
||||
opts := &ljpeg.EncoderOptions{
|
||||
Quality: quality,
|
||||
Quality: jpegEncoderQuality(quality),
|
||||
OptimizeCoding: true,
|
||||
DCTMethod: ljpeg.DCTISlow,
|
||||
}
|
||||
buf := bytes.Buffer{}
|
||||
if err := ljpeg.Encode(&buf, img, opts); err != nil {
|
||||
if err := ljpeg.Encode(&buf, jpeg444Image(img), opts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
@@ -24,9 +25,49 @@ func encodeJPEG(img image.Image, quality int) ([]byte, error) {
|
||||
|
||||
func encodeJPEGToBuf(dst *bytes.Buffer, img image.Image, quality int) error {
|
||||
opts := &ljpeg.EncoderOptions{
|
||||
Quality: quality,
|
||||
Quality: jpegEncoderQuality(quality),
|
||||
OptimizeCoding: true,
|
||||
DCTMethod: ljpeg.DCTISlow,
|
||||
}
|
||||
return ljpeg.Encode(dst, img, opts)
|
||||
return ljpeg.Encode(dst, jpeg444Image(img), opts)
|
||||
}
|
||||
|
||||
// libjpeg preserves the source YCbCr sampling factors, unlike Go's standard
|
||||
// JPEG encoder, so TurboJPEG builds can retain full chroma resolution.
|
||||
func jpeg444Image(src image.Image) image.Image {
|
||||
if src == nil {
|
||||
return src
|
||||
}
|
||||
if ycbcr, ok := src.(*image.YCbCr); ok && ycbcr.SubsampleRatio == image.YCbCrSubsampleRatio444 {
|
||||
return src
|
||||
}
|
||||
|
||||
bounds := src.Bounds()
|
||||
dst := image.NewYCbCr(bounds, image.YCbCrSubsampleRatio444)
|
||||
if rgba, ok := src.(*image.RGBA); ok {
|
||||
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
|
||||
srcOffset := rgba.PixOffset(bounds.Min.X, y)
|
||||
dstOffset := dst.YOffset(bounds.Min.X, y)
|
||||
for x := 0; x < bounds.Dx(); x++ {
|
||||
i := srcOffset + x*4
|
||||
yy, cb, cr := color.RGBToYCbCr(rgba.Pix[i], rgba.Pix[i+1], rgba.Pix[i+2])
|
||||
dst.Y[dstOffset+x] = yy
|
||||
dst.Cb[dstOffset+x] = cb
|
||||
dst.Cr[dstOffset+x] = cr
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
|
||||
for x := bounds.Min.X; x < bounds.Max.X; x++ {
|
||||
pixel := color.NRGBAModel.Convert(src.At(x, y)).(color.NRGBA)
|
||||
yy, cb, cr := color.RGBToYCbCr(pixel.R, pixel.G, pixel.B)
|
||||
offset := dst.YOffset(x, y)
|
||||
dst.Y[offset] = yy
|
||||
dst.Cb[offset] = cb
|
||||
dst.Cr[offset] = cr
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user