我将从我使用的(虚拟)测试图像开始:
这是一个只有 2 种颜色的 32X16 (RGBA) .png:
- 红色(237、28、36)
- 蓝色 (0, 0, 255)
回到问题:[ReadTheDocs.Pillow]: Image.load()(由 open 隐式调用)处理(解码)图像,产生其原始位图数据,这与(编码的)文件内容完全不同。
这是两者之间的区别。
code00.py:
#!/usr/bin/env python
import sys
from PIL import Image
from hashlib import md5
def read_file_data(file_name):
with open(file_name, "rb") as fin:
return fin.read()
def read_img_data(file_name):
with Image.open(file_name) as img:
return img.tobytes()
def process_bytes(buf, first=20, last=20):
print("Len: {:d}\nFirst bytes:\n ".format(len(buf)), end=" ")
for i in range(first):
print("0x{:02X}".format(buf[i]), end=" ")
print("\nLast bytes:\n ", end=" ")
for i in range(-last, 0, 1):
print("0x{:02X}".format(buf[i]), end=" ")
print("\nMD5: {:}".format(md5(buf).hexdigest()))
def main(*argv):
img_name = "rb.png"
funcs = [
read_file_data,
read_img_data,
]
for func in funcs:
print("\nFunction {:s}".format(func.__name__))
b = func(img_name)
process_bytes(b)
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.")
sys.exit(rc)
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q068231412]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###
[prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts\python.exe" code00.py
Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] 064bit on win32
Function read_file_data:
Len: 169
First bytes:
0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A 0x00 0x00 0x00 0x0D 0x49 0x48 0x44 0x52 0x00 0x00 0x00 0x10
Last bytes:
0xE2 0x8A 0x24 0x69 0x53 0x4C 0xB3 0x03 0x00 0x00 0x00 0x00 0x49 0x45 0x4E 0x44 0xAE 0x42 0x60 0x82
MD5: 8368b5c29a12b298cea2ad4b32955830
Function read_img_data:
Len: 2048
First bytes:
0xED 0x1C 0x24 0xFF 0xED 0x1C 0x24 0xFF 0xED 0x1C 0x24 0xFF 0xED 0x1C 0x24 0xFF 0xED 0x1C 0x24 0xFF
Last bytes:
0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF
MD5: ebdf44b7ad36d79b221a70ea2b0fa0c7
Done.
经过几个小时的研究(反复试验,Googleing,阅读 docs 和示例 - 我不能在这里不提[SO]: Get a pixel array from from golang image.Image (@ArunaHerath's answer)),我能够将上述脚本翻译成Go。
code00.go:
package main
import (
"crypto/md5"
"fmt"
"image"
"image/draw"
"io/ioutil"
"os"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
)
type ImageFunc func(string) []byte
type ImageFuncs []ImageFunc
func ReadFileData(fileName string) []byte {
buf, _ := ioutil.ReadFile(fileName)
return buf
}
func ReadImgData(fileName string) []byte {
reader, _ := os.Open(fileName)
defer reader.Close()
img, _, _ := image.Decode(reader)
rect := img.Bounds()
rgba := image.NewRGBA(rect)
draw.Draw(rgba, rect, img, rect.Min, draw.Src)
//fmt.Printf("%v\n", rgba.Pix)
return rgba.Pix
}
func ProcessBytes(buf []byte, first int, last int) {
lb := len(buf)
fmt.Printf("Len: %d\nFirst bytes:\n ", lb)
for i := 0; i < first; i++ {
fmt.Printf("0x%02X ", buf[i])
}
fmt.Printf("\nLast bytes:\n ")
for i := lb - last; i < lb; i++ {
fmt.Printf("0x%02X ", buf[i])
}
fmt.Printf("\nMD5: %x", md5.Sum(buf))
}
func main() {
imgName := "rb.png"
first := 20
last := 20
funcs := ImageFuncs{
ReadFileData,
ReadImgData,
}
for idx := range funcs {
function := funcs[idx]
fmt.Printf("\n\nFunction %#v:\n", function)
b := function(imgName)
ProcessBytes(b, first, last)
}
fmt.Printf("\n\nDone.\n")
}
输出:
[prompt]> "f:\Install\pc064\Google\GoLang\1.16.5\bin\go.exe" run code00.go
Function (main.ImageFunc)(0x9f1060):
Len: 169
First bytes:
0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A 0x00 0x00 0x00 0x0D 0x49 0x48 0x44 0x52 0x00 0x00 0x00 0x10
Last bytes:
0xE2 0x8A 0x24 0x69 0x53 0x4C 0xB3 0x03 0x00 0x00 0x00 0x00 0x49 0x45 0x4E 0x44 0xAE 0x42 0x60 0x82
MD5: 8368b5c29a12b298cea2ad4b32955830
Function (main.ImageFunc)(0x9f10e0):
Len: 2048
First bytes:
0xED 0x1C 0x24 0xFF 0xED 0x1C 0x24 0xFF 0xED 0x1C 0x24 0xFF 0xED 0x1C 0x24 0xFF 0xED 0x1C 0x24 0xFF
Last bytes:
0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF
MD5: ebdf44b7ad36d79b221a70ea2b0fa0c7
Done.
注意事项:
-
重要提示:我只使用(虚拟)RGBA 图像测试了代码,对于其他颜色格式可能需要额外的工作
- 如所见,我没有进行任何错误处理,以保持代码简短(但无论如何,这超出了本问题的范围)