package tools import ( "bytes" "image" "image/color" "image/png" "os" "path/filepath" "testing" ) // makePNG 生成 w×h 的纯色 PNG 文件(可压缩性差的真实体积)。 func makePNG(t *testing.T, w, h int, noise bool) string { t.Helper() img := image.NewRGBA(image.Rect(0, 0, w, h)) seed := uint32(1) next := func() uint8 { seed = seed*1664525 + 1013904223 // LCG 伪随机 return uint8(seed >> 24) } for y := 0; y < h; y++ { for x := 0; x < w; x++ { if noise { // 逐像素伪随机:PNG 压不动,接近真实截图体积 img.SetRGBA(x, y, color.RGBA{next(), next(), next(), 255}) } else { img.SetRGBA(x, y, color.RGBA{200, 100, 50, 255}) } } } p := filepath.Join(t.TempDir(), "big.png") f, err := os.Create(p) if err != nil { t.Fatal(err) } defer f.Close() if err := png.Encode(f, img); err != nil { t.Fatal(err) } return p } // TestShrinkForVision:大 PNG 降采样转 JPEG;小图原样返回。 func TestShrinkForVision(t *testing.T) { big := makePNG(t, 2400, 1600, true) st, _ := os.Stat(big) if st.Size() <= shrinkThresholdBytes { t.Skipf("test png too small (%d bytes), raise noise complexity", st.Size()) } out, err := ShrinkForVision(big) if err != nil { t.Fatal(err) } if out == big { t.Fatal("big png should be shrunk") } if filepath.Ext(out) != ".jpg" { t.Fatalf("expect jpg output, got %s", out) } ost, err := os.Stat(out) if err != nil { t.Fatal(err) } if ost.Size() >= st.Size() { t.Fatalf("shrunk %d should be smaller than original %d", ost.Size(), st.Size()) } // 宽度不超过上限 f, _ := os.Open(out) defer f.Close() img, _, err := image.Decode(f) if err != nil { t.Fatal(err) } if w := img.Bounds().Dx(); w > maxVisionWidth { t.Fatalf("width %d exceeds %d", w, maxVisionWidth) } os.Remove(out) // 小图:原样返回 small := makePNG(t, 64, 64, false) out2, err := ShrinkForVision(small) if err != nil || out2 != small { t.Fatalf("small image passthrough: %q %v", out2, err) } // 非图片文件:原样返回 txt := filepath.Join(t.TempDir(), "x.png") os.WriteFile(txt, []byte("not an image"), 0o644) out3, err := ShrinkForVision(txt) if err != nil || out3 != txt { t.Fatalf("non-image passthrough: %q %v", out3, err) } } // TestVisionJPEGDecodable:压缩产物可被 image/jpeg 解码且尺寸正确。 func TestVisionJPEGDecodable(t *testing.T) { big := makePNG(t, 2000, 1000, true) out, err := ShrinkForVision(big) if err != nil || out == big { t.Fatalf("expected shrink: %q %v", out, err) } data, err := os.ReadFile(out) if err != nil { t.Fatal(err) } if !bytes.HasPrefix(data, []byte{0xFF, 0xD8}) { t.Fatal("output is not JPEG (missing SOI marker)") } }