Нужно записать изображение в PNG файл (Go держит только RGBA и не дает выбирать уровень зжатия). Почитав спецификации, написал это:
Код:
/*
Copyright © 2013 DolphinCommode
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MandelbrotbyBS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fpng
import (
"os"
"log"
"bytes"
"encoding/binary"
"compress/zlib"
"hash/crc32"
)
func ihdr(w, h uint32, depth, color, compression, filter, interlace uint8) []byte {
buffer := make([]byte, 13)
binary.BigEndian.PutUint32(buffer[0:4], w)
binary.BigEndian.PutUint32(buffer[4:8], h)
buffer[8] = byte(depth)
buffer[9] = byte(color)
buffer[10] = byte(compression)
buffer[11] = byte(filter)
buffer[12] = byte(interlace)
return buffer
}
func write_uint32(file *os.File, num uint32) (error) {
buffer := make([]byte, 4)
binary.BigEndian.PutUint32(buffer, num)
_, err := file.Write(buffer)
return err
}
func write_chunk(file *os.File, name string, data []byte) {
write_uint32(file, uint32(len(data))) //Length
_, err := file.Write([]byte(name)) //Chunk type
if err != nil {
log.Fatal(err)
}
_, err = file.Write(data) //Chunk data
if err != nil {
log.Fatal(err)
}
crc := crc32.ChecksumIEEE([]byte(name+string(data))) //crc32
write_uint32(file, crc) //crc32
}
func Write(file *os.File, x, y uint32, img []uint8, level int) {
_, err := file.Write([]byte("\x89PNG\x0D\x0A\x1A\x0A"))
if err != nil {
log.Fatal(err)
}
write_chunk(file, "IHDR", ihdr(x, y, 8, 2, 0, 0, 0)) //ihdr
var cdata bytes.Buffer
if err != nil {
log.Fatal(err)
}
ccdata, err := zlib.NewWriterLevel(&cdata, level)
if err != nil {
log.Fatal(err)
}
_, err = ccdata.Write(img)
if err != nil {
log.Fatal(err)
}
write_chunk(file, "IDAT", cdata.Bytes())
ccdata.Close()
write_chunk(file, "IEND", []byte{})
}
В итоге, если попытаться открыть файл ImageMagick (display), он выдает ошибку:
Код: Выделить всё
display: Ignoring bad adaptive filter type `out.png' @ warning/png.c/MagickPNGWarningHandler/1787.
display: Not enough image data `out.png' @ error/png.c/MagickPNGErrorHandler/1761.
display: corrupt image `out.png' @ error/png.c/ReadPNGImage/3903.Чанки формирую и записываю правильно. Использую только минимум: IHDR, IDAT, IEND.