Merge branch 'fix-report' into 'master'

change: compress html report image with quality 50

See merge request iesqa/httprunner!136
This commit is contained in:
李隆
2025-07-28 06:01:33 +00:00
4 changed files with 21 additions and 100 deletions

View File

@@ -64,7 +64,7 @@ func NewGA4Client(measurementID, apiSecret string, debug ...bool) *GA4Client {
apiSecret: apiSecret,
userID: userID,
httpClient: &http.Client{
Timeout: 5 * time.Second,
Timeout: 10 * time.Second,
},
debug: dbg,
}
@@ -206,6 +206,6 @@ func SendGA4Event(name string, params map[string]interface{}) {
}
err := ga4Client.SendEvent(event)
if err != nil {
log.Warn().Err(err).Msg("send GA4 event failed")
log.Debug().Err(err).Msg("send GA4 event failed")
}
}

View File

@@ -1 +1 @@
v5.0.0-250724
v5.0.0-250728

View File

@@ -343,9 +343,8 @@ func (g *HTMLReportGenerator) encodeImageToBase64(imagePath string) string {
return ""
}
// Read and compress the image using the unified compression function
// Enable resize with max width 800px for HTML reports
compressedData, err := uixt.CompressImageFile(imagePath, true, 800)
// Read and compress the image with quality 50
compressedData, err := uixt.CompressImageFile(imagePath, 50)
if err != nil {
log.Warn().Err(err).Str("path", imagePath).Msg("failed to compress image, using original")
// Fallback to original image if compression fails

View File

@@ -7,7 +7,6 @@ import (
"image"
"image/color"
"image/draw"
"image/gif"
"image/jpeg"
"image/png"
"math"
@@ -244,8 +243,8 @@ func getScreenShotBuffer(driver IDriver) (compressedBufSource *bytes.Buffer, err
"take screenshot failed %v", err)
}
// compress screenshot
compressBufSource, err := compressImageBufferWithOptions(bufSource, false, 800)
// compress screenshot with quality 95
compressBufSource, err := compressImageBufferWithOptions(bufSource, 95)
if err != nil {
return nil, errors.Wrapf(code.DeviceScreenShotError,
"compress screenshot failed %v", err)
@@ -262,11 +261,7 @@ func saveScreenShot(raw *bytes.Buffer, screenshotPath string) error {
log.Error().Err(err).Msg("copy screenshot buffer failed")
}
img, format, err := image.Decode(copiedBuffer)
if err != nil {
return errors.Wrap(err, "decode screenshot image failed")
}
// create file
file, err := os.Create(screenshotPath)
if err != nil {
return errors.Wrap(err, "create screenshot image file failed")
@@ -275,26 +270,10 @@ func saveScreenShot(raw *bytes.Buffer, screenshotPath string) error {
_ = file.Close()
}()
// compress image and save to file
switch format {
case "jpeg":
jpegOptions := &jpeg.Options{Quality: 95}
err = jpeg.Encode(file, img, jpegOptions)
case "png":
encoder := png.Encoder{
CompressionLevel: png.BestCompression,
}
err = encoder.Encode(file, img)
case "gif":
gifOptions := &gif.Options{
NumColors: 256,
}
err = gif.Encode(file, img, gifOptions)
default:
return fmt.Errorf("unsupported image format %s", format)
}
// directly write compressed JPEG data to avoid quality loss
_, err = file.Write(copiedBuffer.Bytes())
if err != nil {
return errors.Wrap(err, "save image file failed")
return errors.Wrap(err, "write image file failed")
}
var fileSize int64
@@ -303,14 +282,14 @@ func saveScreenShot(raw *bytes.Buffer, screenshotPath string) error {
fileSize = fileInfo.Size()
}
log.Info().Str("path", screenshotPath).
Int("rawBytes", raw.Len()).Int64("saveBytes", fileSize).
Int64("fileSize", fileSize).
Msg("save screenshot file success")
return nil
}
// compressImageBufferWithOptions compresses image buffer with advanced options
func compressImageBufferWithOptions(raw *bytes.Buffer, enableResize bool, maxWidth int) (compressed *bytes.Buffer, err error) {
func compressImageBufferWithOptions(raw *bytes.Buffer, quality int) (compressed *bytes.Buffer, err error) {
rawSize := raw.Len()
// decode image from buffer
img, format, err := image.Decode(raw)
@@ -318,32 +297,12 @@ func compressImageBufferWithOptions(raw *bytes.Buffer, enableResize bool, maxWid
return nil, err
}
// Get original image dimensions
bounds := img.Bounds()
originalWidth := bounds.Dx()
originalHeight := bounds.Dy()
// Calculate new dimensions for compression if resize is enabled
var newWidth, newHeight int
var resizedImg image.Image = img
if enableResize && originalWidth > maxWidth {
ratio := float64(maxWidth) / float64(originalWidth)
newWidth = maxWidth
newHeight = int(float64(originalHeight) * ratio)
resizedImg = resizeImage(img, newWidth, newHeight)
} else {
newWidth = originalWidth
newHeight = originalHeight
}
jpegQuality := 95
var buf bytes.Buffer
switch format {
case "jpeg", "jpg", "png":
// compress with compression rate of 95
jpegOptions := &jpeg.Options{Quality: jpegQuality}
err = jpeg.Encode(&buf, resizedImg, jpegOptions)
// compress with compression rate
jpegOptions := &jpeg.Options{Quality: quality}
err = jpeg.Encode(&buf, img, jpegOptions)
if err != nil {
return nil, err
}
@@ -354,55 +313,18 @@ func compressImageBufferWithOptions(raw *bytes.Buffer, enableResize bool, maxWid
compressedSize := buf.Len()
log.Debug().
Int("rawSize", rawSize).
Int("originalWidth", originalWidth).
Int("originalHeight", originalHeight).
Int("newWidth", newWidth).
Int("newHeight", newHeight).
Int("jpegQuality", jpegQuality).
Int("quality", quality).
Int("compressedSize", compressedSize).
Bool("resized", enableResize && originalWidth > maxWidth).
Msg("compress image buffer")
// return compressed image buffer
return &buf, nil
}
// resizeImage resizes an image using simple nearest neighbor algorithm
func resizeImage(src image.Image, width, height int) image.Image {
srcBounds := src.Bounds()
srcWidth := srcBounds.Dx()
srcHeight := srcBounds.Dy()
// Create a new image with the target dimensions
dst := image.NewRGBA(image.Rect(0, 0, width, height))
// Simple nearest neighbor resizing
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
// Map destination coordinates to source coordinates
srcX := x * srcWidth / width
srcY := y * srcHeight / height
// Ensure we don't go out of bounds
if srcX >= srcWidth {
srcX = srcWidth - 1
}
if srcY >= srcHeight {
srcY = srcHeight - 1
}
// Copy pixel from source to destination
dst.Set(x, y, src.At(srcBounds.Min.X+srcX, srcBounds.Min.Y+srcY))
}
}
return dst
}
// CompressImageFile compresses an image file and returns the compressed data
func CompressImageFile(imagePath string, enableResize bool, maxWidth int) ([]byte, error) {
log.Debug().Str("imagePath", imagePath).Bool("enableResize", enableResize).
Int("maxWidth", maxWidth).Msg("compress image file")
func CompressImageFile(imagePath string, quality int) ([]byte, error) {
log.Debug().Str("imagePath", imagePath).
Int("quality", quality).Msg("compress image file")
// Read the original image file
file, err := os.Open(imagePath)
@@ -419,7 +341,7 @@ func CompressImageFile(imagePath string, enableResize bool, maxWidth int) ([]byt
}
// Compress using the buffer compression function
compressedBuf, err := compressImageBufferWithOptions(&buf, enableResize, maxWidth)
compressedBuf, err := compressImageBufferWithOptions(&buf, quality)
if err != nil {
return nil, fmt.Errorf("failed to compress image: %w", err)
}