mirror of
https://github.com/celogeek/go-comic-converter.git
synced 2025-06-23 05:39:55 +02:00
85 lines
1.8 KiB
Go
85 lines
1.8 KiB
Go
package epubzip
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"compress/flate"
|
|
"fmt"
|
|
"hash/crc32"
|
|
"image"
|
|
"image/jpeg"
|
|
"image/png"
|
|
"time"
|
|
)
|
|
|
|
type Image struct {
|
|
Header *zip.FileHeader
|
|
Data []byte
|
|
}
|
|
|
|
var naiveJFIFHeader = []byte{
|
|
0xFF, 0xD8, // SOI
|
|
0xFF, 0xE0, // APP0 Marker
|
|
0x00, 0x10, // Length
|
|
0x4A, 0x46, 0x49, 0x46, 0x00, // JFIF\0
|
|
0x01, 0x02, // 1.02
|
|
0x00, // Density type
|
|
0x00, 0x01, // X Density
|
|
0x00, 0x01, // Y Density
|
|
0x00, 0x00, // No Thumbnail
|
|
}
|
|
|
|
// CompressImage create gzip encoded jpeg
|
|
func CompressImage(filename string, format string, img image.Image, quality int) (Image, error) {
|
|
var (
|
|
data, cdata bytes.Buffer
|
|
err error
|
|
)
|
|
|
|
switch format {
|
|
case "png":
|
|
err = png.Encode(&data, img)
|
|
case "jpeg":
|
|
// static JFIF header for better compatibility with Kindle devices
|
|
var b bytes.Buffer
|
|
err = jpeg.Encode(&b, img, &jpeg.Options{Quality: quality})
|
|
data.Write(naiveJFIFHeader)
|
|
data.Write(b.Bytes()[2:])
|
|
default:
|
|
err = fmt.Errorf("unknown format %q", format)
|
|
}
|
|
if err != nil {
|
|
return Image{}, err
|
|
}
|
|
|
|
wcdata, err := flate.NewWriter(&cdata, flate.BestCompression)
|
|
if err != nil {
|
|
return Image{}, err
|
|
}
|
|
|
|
_, err = wcdata.Write(data.Bytes())
|
|
if err != nil {
|
|
return Image{}, err
|
|
}
|
|
|
|
err = wcdata.Close()
|
|
if err != nil {
|
|
return Image{}, err
|
|
}
|
|
|
|
t := time.Now()
|
|
//goland:noinspection GoDeprecation
|
|
return Image{
|
|
&zip.FileHeader{
|
|
Name: filename,
|
|
CompressedSize64: uint64(cdata.Len()),
|
|
UncompressedSize64: uint64(data.Len()),
|
|
CRC32: crc32.Checksum(data.Bytes(), crc32.IEEETable),
|
|
Method: zip.Deflate,
|
|
ModifiedTime: uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11),
|
|
ModifiedDate: uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9),
|
|
},
|
|
cdata.Bytes(),
|
|
}, nil
|
|
}
|