zoukankan      html  css  js  c++  java
  • Go语言中对图像进行缩放

    由Google开发,简洁、高效、开源的Go语言日渐成为语言新宠。它专门针对多处理器系统应用程序的编程进行优化,使得Go编译的程序与C或C++代码的速度相媲美,且更安全、支持并行进程。Go语言在Go1版本上支持Windows, 苹果Mac OS X, Linux和FreeBSD操作系统。Go支持面向对象,而且具有真正的封装(closures)和反射 (reflection)等功能。

    在学习曲线方面,派克认为Go与Java类似,对于Java开发者来说,应该能够轻松学会 Go。同样,对于C#开发者来说,也很轻松学会GO语言。

    笔者对图形图像研究很感兴趣,让我们来看看Go语言中对图像进行缩放的解决方案:

    package resize


    import (
    "image"
    "image/color"
    )


    // average convert the sums to averages and returns the result.
    func average(sum []uint64, w, h int, n uint64) *image.RGBA {
    ret := image.NewRGBA(image.Rect(0, 0, w, h))
    for y := 0; y < h; y++ {
    for x := 0; x < w; x++ {
    index := 4 * (y*w + x)
    pix := ret.Pix[y*ret.Stride+x*4:]
    pix[0] = uint8(sum[index+0] / n)
    pix[1] = uint8(sum[index+1] / n)
    pix[2] = uint8(sum[index+2] / n)
    pix[3] = uint8(sum[index+3] / n)
    }
    }
    return ret
    }


    // ResizeRGBA returns a scaled copy of the RGBA image slice r of m.
    // The returned image has width w and height h.
    func ResizeRGBA(m *image.RGBA, r image.Rectangle, w, h int) *image.RGBA {
    ww, hh := uint64(w), uint64(h)
    dx, dy := uint64(r.Dx()), uint64(r.Dy())
    // See comment in Resize.
    n, sum := dx*dy, make([]uint64, 4*w*h)
    for y := r.Min.Y; y < r.Max.Y; y++ {
    pix := m.Pix[(y-r.Min.Y)*m.Stride:]
    for x := r.Min.X; x < r.Max.X; x++ {
    // Get the source pixel.
    p := pix[(x-r.Min.X)*4:]
    r64 := uint64(p[0])
    g64 := uint64(p[1])
    b64 := uint64(p[2])
    a64 := uint64(p[3])
    // Spread the source pixel over 1 or more destination rows.
    py := uint64(y) * hh
    for remy := hh; remy > 0; {
    qy := dy - (py % dy)
    if qy > remy {
    qy = remy
    }
    // Spread the source pixel over 1 or more destination columns.
    px := uint64(x) * ww
    index := 4 * ((py/dy)*ww + (px / dx))
    for remx := ww; remx > 0; {
    qx := dx - (px % dx)
    if qx > remx {
    qx = remx
    }
    qxy := qx * qy
    sum[index+0] += r64 * qxy
    sum[index+1] += g64 * qxy
    sum[index+2] += b64 * qxy
    sum[index+3] += a64 * qxy
    index += 4
    px += qx
    remx -= qx
    }
    py += qy
    remy -= qy
    }
    }
    }
    return average(sum, w, h, n)
    }


    // ResizeNRGBA returns a scaled copy of the RGBA image slice r of m.
    // The returned image has width w and height h.
    func ResizeNRGBA(m *image.NRGBA, r image.Rectangle, w, h int) *image.RGBA {
    ww, hh := uint64(w), uint64(h)
    dx, dy := uint64(r.Dx()), uint64(r.Dy())
    // See comment in Resize.
    n, sum := dx*dy, make([]uint64, 4*w*h)
    for y := r.Min.Y; y < r.Max.Y; y++ {
    pix := m.Pix[(y-r.Min.Y)*m.Stride:]
    for x := r.Min.X; x < r.Max.X; x++ {
    // Get the source pixel.
    p := pix[(x-r.Min.X)*4:]
    r64 := uint64(p[0])
    g64 := uint64(p[1])
    b64 := uint64(p[2])
    a64 := uint64(p[3])
    r64 = (r64 * a64) / 255
    g64 = (g64 * a64) / 255
    b64 = (b64 * a64) / 255
    // Spread the source pixel over 1 or more destination rows.
    py := uint64(y) * hh
    for remy := hh; remy > 0; {
    qy := dy - (py % dy)
    if qy > remy {
    qy = remy
    }
    // Spread the source pixel over 1 or more destination columns.
    px := uint64(x) * ww
    index := 4 * ((py/dy)*ww + (px / dx))
    for remx := ww; remx > 0; {
    qx := dx - (px % dx)
    if qx > remx {
    qx = remx
    }
    qxy := qx * qy
    sum[index+0] += r64 * qxy
    sum[index+1] += g64 * qxy
    sum[index+2] += b64 * qxy
    sum[index+3] += a64 * qxy
    index += 4
    px += qx
    remx -= qx
    }
    py += qy
    remy -= qy
    }
    }
    }
    return average(sum, w, h, n)
    }


    // Resample returns a resampled copy of the image slice r of m.
    // The returned image has width w and height h.
    func Resample(m image.Image, r image.Rectangle, w, h int) *image.RGBA {
    if w < 0 || h < 0 {
    return nil
    }
    if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 {
    return image.NewRGBA(image.Rect(0, 0, w, h))
    }
    curw, curh := r.Dx(), r.Dy()
    img := image.NewRGBA(image.Rect(0, 0, w, h))
    for y := 0; y < h; y++ {
    for x := 0; x < w; x++ {
    // Get a source pixel.
    subx := x * curw / w
    suby := y * curh / h
    r32, g32, b32, a32 := m.At(subx, suby).RGBA()
    r := uint8(r32 >> 8)
    g := uint8(g32 >> 8)
    b := uint8(b32 >> 8)
    a := uint8(a32 >> 8)
    img.SetRGBA(x, y, color.RGBA{r, g, b, a})
    }
    }
    return img

    }

    有了上面的基础,下文讲解 利用Go语言上传图像并生成缩略图

  • 相关阅读:
    shell的执行顺序问题
    七层负载均衡——HAProxy
    不要自以为是码农
    SSL协议运行机制
    Linux启动流程
    MIM协议与Base64编码
    Adele的生活
    你值得拥有:25个Linux性能监控工具
    [Zabbix] 如何实现邮件报警通知以及免费短信报警通知
    php.ini中date.timezone设置分析
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3017561.html
Copyright © 2011-2022 走看看