doumi1884 2018-07-12 09:49
浏览 115

为什么Bild中的jpeg.Decode(bytes.NewReader(imageBytes))和jpeg.Encode(buf,img,nil)占用大量CPU?

I am trying to build an application which manipulates images on the run using Bild. But the above-mentioned methods are eating up a lot CPU(90%) for images. What is the reason for these methods to use high CPU? Are there any other methods or packages which uses less CPU?

func imageDecode(imageBytes []byte) (image.Image, error) {
    contentType := http.DetectContentType(imageBytes)
    var err error
    var img image.Image
    if contentType == constants.PngContentType {
        img, err = png.Decode(bytes.NewReader(imageBytes))
    } else if contentType == constants.JpegContentType {
        img, err = jpeg.Decode(bytes.NewReader(imageBytes))
    } else if contentType == constants.GifContentType {
        img, err = gif.Decode(bytes.NewReader(imageBytes))
    } else {
        img, err = nil, fmt.Errorf("decode error invalid content-type for filename: ")
    }
    if err != nil {
        return img, err
    }
    return img, nil
}

func imageEncode(imageBytes []byte, img image.Image) ([]byte, error) {
    contentType := http.DetectContentType(imageBytes)
    if contentType == constants.PngContentType && isOpaque(img) {
        contentType = constants.JpegContentType
    }
    buf := new(bytes.Buffer)
    var err error
    var transformedImageBytes []byte
    if contentType == constants.PngContentType {
        pngEnc := png.Encoder{CompressionLevel: png.BestCompression}
        err = pngEnc.Encode(buf, img)
    } else if contentType == constants.JpegContentType {
        err = jpeg.Encode(buf, img, nil)
    } else if contentType == constants.GifContentType {
        err = gif.Encode(buf, img, nil)
    } else {
        err = fmt.Errorf("encode error invalid content-type")
    }
    if err != nil {
        return transformedImageBytes, err
    }
    transformedImageBytes = buf.Bytes()
    return transformedImageBytes, err
}
  • 写回答

1条回答 默认 最新

  • dtwvr26066 2018-07-12 10:29
    关注

    You don't need to manually detect the image type and use different decoding calls, the image package does that for you already, when using image.Decode(). Just make sure you have the image decoders registered prior, which you can achieve by using blank imports, e.g.:

    import (
        _ "image/gif"
        _ "image/jpeg"
        _ "image/png"
    )
    
    func imageDecode(imageBytes []byte) (image.Image, error) {
        img, _, err := image.Decode(bytes.NewReader(imageBytes))
    }
    

    Although I'm not sure performance will improve significantly by this.

    What you should do is use "smart" conversion. By this I mean in certain cases you can omit decoding and re-encoding the image, you can just send the input to the output as-is (e.g. using io.Copy()):

    • If input is a GIF image.
    • If input is a JPEG image.

    You only have to truly decode the image if it is of PNG format. Note that detecting if a PNG image is opaque is slow as it has to examine all the pixels (unless a transparent pixel is found earlier).

    评论

报告相同问题?

悬赏问题

  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 matlab有关常微分方程的问题求解决
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考