package thumbs import ( "bytes" "image" "image/color" "image/jpeg" "image/png" "testing" ) func makePNG(t *testing.T, w, h int, transparent bool) []byte { t.Helper() img := image.NewRGBA(image.Rect(0, 0, w, h)) for y := 0; y < h; y++ { for x := 0; x < w; x++ { // 左红右绿两半,方便验证盒均值没把通道混错 c := color.RGBA{255, 0, 0, 255} if x >= w/2 { c = color.RGBA{0, 255, 0, 255} } if transparent { c = color.RGBA{0, 0, 0, 0} } img.Set(x, y, c) } } var b bytes.Buffer if err := png.Encode(&b, img); err != nil { t.Fatal(err) } return b.Bytes() } func TestGenerateDownscale(t *testing.T) { src := makePNG(t, 800, 400, false) out, mime, pass, err := Generate(src, "image/png", 400) if err != nil { t.Fatal(err) } if pass { t.Fatal("800px 图在 w=400 不应直通") } if mime != "image/jpeg" { t.Fatalf("mime=%s", mime) } cfg, _, err := image.DecodeConfig(bytes.NewReader(out)) if err != nil { t.Fatal(err) } if cfg.Width != 400 || cfg.Height != 200 { t.Fatalf("got %dx%d, want 400x200", cfg.Width, cfg.Height) } img, err := jpeg.Decode(bytes.NewReader(out)) if err != nil { t.Fatal(err) } // 盒均值后左右两半的中心仍是红/绿(容差给 JPEG 质量 82 留余量) r, g, _, _ := img.At(100, 100).RGBA() if r>>8 < 200 || g>>8 > 60 { t.Fatalf("左半应偏红: r=%d g=%d", r>>8, g>>8) } r, g, _, _ = img.At(300, 100).RGBA() if g>>8 < 200 || r>>8 > 60 { t.Fatalf("右半应偏绿: r=%d g=%d", r>>8, g>>8) } } func TestGeneratePassThrough(t *testing.T) { src := makePNG(t, 300, 150, false) out, mime, pass, err := Generate(src, "image/png", 960) if err != nil { t.Fatal(err) } if !pass || mime != "image/png" || !bytes.Equal(out, src) { t.Fatalf("小图应原样直通 pass=%v mime=%s", pass, mime) } } func TestGenerateRejectsGarbage(t *testing.T) { if _, _, _, err := Generate([]byte("not an image"), "image/jpeg", 400); err == nil { t.Fatal("垃圾字节应报错") } } func TestFlattenAlphaUnpremultiply(t *testing.T) { // 50% 透明的纯红:alpha=128 预乘 R=128,还原应为 R≈255 img := image.NewNRGBA(image.Rect(0, 0, 1, 1)) img.Set(0, 0, color.NRGBA{255, 0, 0, 128}) flat := flatten(img, img.Bounds()) if flat[0] < 240 || flat[3] != 128 { t.Fatalf("unpremultiply wrong: r=%d a=%d", flat[0], flat[3]) } }