Golang-实现图片缩放

package main

import (
    "fmt"
    "graphics"
    "image"
    "image/png"
    "log"
    "net/http"
    "os"
    "strconv"
    "strings"
)
func main() {
    http.HandleFunc("/", doImageHandler)
    http.ListenAndServe("127.0.0.1:6789", nil)
}

func doImageHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Printf("%q\n", strings.Split(r.URL.Path, "/"))
    url := strings.Split(r.URL.Path, "/")
    if len(url) != 3 {
    return
    }
    newdx, uerr := strconv.Atoi(url[1])
    if uerr != nil {
    log.Fatal(uerr)
    }
    src, err := LoadImage(url[2])
    bound := src.Bounds()
    dx := bound.Dx()
    dy := bound.Dy()
    if err != nil {
    log.Fatal(err)
    }
    // 缩略图的大小
    dst := image.NewRGBA(image.Rect(0, 0, newdx, newdx*dy/dx))
    // 产生缩略图,等比例缩放
    err = graphics.Scale(dst, src)
    if err != nil {
    log.Fatal(err)
    }
    header := w.Header()
    header.Add("Content-Type", "image/jpeg")

    png.Encode(w, dst)
}


// Load Image decodes an image from a file of image.
func LoadImage(path string) (img image.Image, err error) {
    file, err := os.Open(path)
    if err != nil {
    return
    }
    defer file.Close()
    img, _, err = image.Decode(file)
    return
}

///////////////////////////////////////////////////////////////////////

package mas

import (
    "code.google.com/p/graphics-go/graphics"
    "fmt"
    z "github.com/nutzam/zgo"
    "image"
)

func (ma *Master) ActiveImage(pobj string) error {

    // 文件绝对路径
    var path string = pobj

    // 保留源图Image结构
    var img image.Image

    // 图片类型
    typef := z.FileType(path)

    // 按照图片格式加载图片
    switch typef {
    // JPEG
    case "jpeg":
    // ImageJPEG
    img = z.ImageJPEG(path)
    // JPG
    case "jpg":
    // ImageJPEG
    img = z.ImageJPEG(path)
    // PNG
    case "png":
    // ImagePNG
    img = z.ImagePNG(path)
    }

    // 判断加载原图片是否成功
    if img == nil {
    // 返回错误
    return fmt.Errorf("active image decode exception ...")
    }

    // -------------------------------------------------------- //

    // 获取屏幕数量
    moniSize := ma.NodeConf.MonitorSize(ma)

    // 获取屏幕分辨率
    width := ma.NodeConf.Resolution.Width
    height := ma.NodeConf.Resolution.Height

    // 获取素材平均值
    widthMoni := img.Bounds().Dx() / moniSize.Col
    heightMoni := img.Bounds().Dy() / moniSize.Row

    // -------------------------------------------------------- //

    // 遍历屏幕,切割图片
    for _, monis := range ma.NodeConf.Layout {

    // 遍历节点屏幕
    for _, moni := range monis {

        // 获取图片
        row := moni.Display.Row
        col := moni.Display.Col

        // 生成目标背景图
        backgroundSrc := z.ImageRGBA(widthMoni, heightMoni)

        // 生成目标图
        z.ImageDrawRGBA(backgroundSrc, img, (col-1)*widthMoni, (row-1)*heightMoni)

        // 生成最终背景图
        background := z.ImageRGBA(width, height)

        // 产生最终图
        graphics.Scale(background, backgroundSrc)

        // 按照图片格式保存图片
        switch typef {
        // JPEG
        case "jpeg":
        // ImageEncodeJPEG
        z.ImageEncodeJPEG(fmt.Sprintf("%s.pic_result/%d_%d.%s", path, col, row, typef), background)
        // JPG
        case "jpg":
        // ImageEncodeJPEG
        z.ImageEncodeJPEG(fmt.Sprintf("%s.pic_result/%d_%d.%s", path, col, row, typef), background)
        // PNG
        case "png":
        // ImageEncodePNG
        z.ImageEncodePNG(fmt.Sprintf("%s.pic_result/%d_%d.%s", path, col, row, typef), background)
        }

    }

    }

    // 返回
    return nil

}

///////////////////////////////////////////////////////////////

package z

import (
    "image"
    "image/draw"
    "image/jpeg"
    "image/png"
    "os"
)

// 读取JPEG图片返回image.Image对象
func ImageJPEG(ph string) image.Image {
    // 打开图片文件
    f, fileErr := os.Open(ph)
    if fileErr != nil {
    return nil
    }
    // 退出时关闭文件
    defer f.Close()
    // 解码
    j, jErr := jpeg.Decode(f)
    if jErr != nil {
    return nil
    }
    // 返回解码后的图片
    return j
}

// 读取PNG图片返回image.Image对象
func ImagePNG(ph string) image.Image {
    // 打开图片文件
    f, fileErr := os.Open(ph)
    if fileErr != nil {
    return nil
    }
    // 退出时关闭文件
    defer f.Close()
    // 解码
    p, pErr := png.Decode(f)
    if pErr != nil {
    return nil
    }
    // 返回解码后的图片
    return p
}

// 按照分辨率创建一张空白图片对象
func ImageRGBA(width, height int) *image.RGBA {
    // 建立图像,image.Rect(最小X,最小Y,最大X,最小Y)
    return image.NewRGBA(image.Rect(0, 0, width, height))
}

// 将图片绘制到图片
func ImageDrawRGBA(img *image.RGBA, imgcode image.Image, x, y int) {
    // 绘制图像
    // image.Point A点的X,Y坐标,轴向右和向下增加{0,0}
    // image.ZP ZP is the zero Point
    // image.Pt Pt is shorthand for Point{X, Y}
    draw.Draw(img, img.Bounds(), imgcode, image.Pt(x, y), draw.Over)
}

// JPEG将编码生成图片
// 选择编码参数,质量范围从1到100,更高的是更好 &jpeg.Options{90}
func ImageEncodeJPEG(ph string, img image.Image) error {
    // 确保文件父目录存在
    FcheckParents(ph)
    // 打开文件等待写入
    f := FileW(ph)
    // 保证文件正常关闭
    defer f.Close()
    // 写入文件
    return jpeg.Encode(f, img, &jpeg.Options{100})
}

// PNG将编码生成图片
func ImageEncodePNG(ph string, img image.Image) error {
    // 确保文件父目录存在
    FcheckParents(ph)
    // 打开文件等待写入
    f := FileW(ph)
    // 保证文件正常关闭
    defer f.Close()
    // 写入文件
    return png.Encode(f, img)
}

本文分享自微信公众号 - Golang语言社区(Golangweb)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-04-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯高校合作

【倒计时7天】2018教育部-腾讯公司产学合作协同育人项目申请即将截止!

16220
来自专栏腾讯社交用户体验设计

ISUX Xcube智能一键生成H5

51620
来自专栏怀英的自我修炼

考研英语-1-导学

英二图表作文要重视。总体而言,英语一会比英语二难点。不过就写作而言,英语二会比英语一有难度,毕竟图表作文并不好写。

12410
来自专栏Ken的杂谈

【系统设置】CentOS 修改机器名

18430
来自专栏前端桃园

知识体系解决迷茫的你

最近在星球里群里都有小伙伴说道自己对未来的路比较迷茫,一旦闲下来就不知道自己改干啥,今天我这篇文章就是让你觉得一天给你 25 个小时你都不够用,觉得睡觉都是浪费...

22740
来自专栏钱塘大数据

中国互联网协会发布:《2018中国互联网发展报告》

在2018中国互联网大会闭幕论坛上,中国互联网协会正式发布《中国互联网发展报告2018》(以下简称《报告》)。《中国互联网发展报告》是由中国互联网协会与中国互联...

13850
来自专栏微信公众号:小白课代表

不只是软件,在线也可以免费下载百度文库了。

不管是学生,还是职场员工,下载各种文档几乎是不可避免的,各种XXX.docx,XXX.pptx更是家常便饭,人们最常用的就是百度文库,豆丁文库,道客巴巴这些下载...

45130
来自专栏haifeiWu与他朋友们的专栏

复杂业务下向Mysql导入30万条数据代码优化的踩坑记录

从毕业到现在第一次接触到超过30万条数据导入MySQL的场景(有点low),就是在顺丰公司接入我司EMM产品时需要将AD中的员工数据导入MySQL中,因此楼主负...

31040
来自专栏FSociety

SQL中GROUP BY用法示例

GROUP BY我们可以先从字面上来理解,GROUP表示分组,BY后面写字段名,就表示根据哪个字段进行分组,如果有用Excel比较多的话,GROUP BY比较类...

5.2K20
来自专栏钱塘大数据

理工男图解零维到十维空间,烧脑已过度,受不了啦!

让我们从一个点开始,和我们几何意义上的点一样,它没有大小、没有维度。它只是被想象出来的、作为标志一个位置的点。它什么也没有,空间、时间通通不存在,这就是零维度。

35430

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励