1. 程式人生 > 其它 >Golang-實現圖片縮放

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("%qn", 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)
}