package epubzip import ( "archive/zip" "bytes" "compress/flate" "fmt" "hash/crc32" "image" "image/jpeg" "os" "time" ) type ZipImage struct { Header *zip.FileHeader Data []byte } // compressed size of the image with the header func (img *ZipImage) CompressedSize() uint64 { return img.Header.CompressedSize64 + 30 + uint64(len(img.Header.Name)) } func exitWithError(err error) { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // create gzip encoded jpeg func CompressImage(filename string, img image.Image, quality int) *ZipImage { var ( data, cdata bytes.Buffer err error ) err = jpeg.Encode(&data, img, &jpeg.Options{Quality: quality}) if err != nil { exitWithError(err) } wcdata, err := flate.NewWriter(&cdata, flate.BestCompression) if err != nil { exitWithError(err) } _, err = wcdata.Write(data.Bytes()) if err != nil { exitWithError(err) } err = wcdata.Close() if err != nil { exitWithError(err) } t := time.Now() return &ZipImage{ &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(), } }