Go 處理 PNG 圖片及 Mac 圖片集轉 PDF

【導讀】Kindle 用戶福利!本文中作者介紹瞭如何使用 Go 程序方便地處理 PDF 電子書。

用 Kindle 看自己的電子書,需要以郵件的方式發送到自己的 Kindle 的郵箱裏,其中電子書作爲該郵件的附件。這個附件的要求是直接附件,不能是雲附件。大部分郵箱對附件的處理是當附件的大小大於某個值時(如:大於 30M)則作爲雲附件進行發送。作爲雲附件發送的電子書,Kindle 的回覆是:您發送至 Kindle 的郵件未附任何文件附件。

一、爲什麼想到用 Go 的 PNG 圖片處理。

人在湖北農村,兒女學習需要電子書,學校提供了微信免費版。但限於網速,常常無法加載(每次打開都需要重新加載),所以無法正常使用,只好另作處理。我的處理方法是:首先,將微信版的電子書下載下來(這裏不講這個);其次,打包成 PDF 發送到我的 Kindle;最後,從 Kindle 看(只需要下載一次)。由於郵箱與 Kindle 的限制,需要壓縮圖片。

處理圖片,首先當然想到的是 Photoshop,設置好存儲動作,然後使用批處理。但我現在沒有,所以自己來寫一個。

寫這種小程序,首先想到的 Go 與 Python,我決定用 Go。

二、Go 的 PNG 圖片處理方法。

處理方法很簡單,記錄下來的原因有兩個。一個是:PNG 圖片的大小與色彩的多少有關,當然也與色彩分佈的複雜度也有關。另一個是:Mac 中圖片集轉 PDF 需要有一個筆記。

> image
main.go
package main

import (
 "fmt"
 "image"
 "image/color"
 "image/png"
 "log"
 "math"
 "os"
)

var path = "image/root畫板 %d@3x.png"

func main() {
        // 按順序讀取所有圖片。
 for i := 1; i < 201; i++ {
                // 原圖片文件路徑。
  f := fmt.Sprintf(path, i)
                // 打開源圖片文件。
                source := sourceImage(f)
                // 打開目標圖片文件
  target := targetImage(i)
  // 將源圖片文件另存爲目標圖片文件。
  saveAs(source, target)
 }
}

// 新建目標圖片文件。
func targetImage(i int) *os.File {
 file, err := os.Create(fmt.Sprintf("%d.png", i))
 if err != nil {
  log.Fatal(err)
 }
 return file
}

// 打開原圖片文件。
func sourceImage(image string) *os.File {
 file, err := os.Open(image)
 if err != nil {
  log.Fatal(err)
 }
 return file
}

func saveAs(source, target *os.File) bool {
        // 延遲關閉文件源。
 defer source.Close()
 defer target.Close()
        
 // 解碼源圖片文件內容。
 s, err := png.Decode(source)
 if err != nil {
  log.Fatal(err)
 }
 
 // 獲取源圖片的大小。
 bounds := s.Bounds()
 w := bounds.Max.X
 h := bounds.Max.Y

 // 新建一個Image。
 grayScale := image.NewGray(image.Rectangle{image.Point{0, 0}, image.Point{w, h}})
 for x := 0; x < w; x++ {
  for y := 0; y < h; y++ {
                        // 將每個點的顏色轉爲指定灰度。
   input := s.At(x, y)
   g := formatGray(input)
                        // 寫入灰度值。
   grayScale.Set(x, y, g)
  }
 }
        
 // 編碼新的圖片內容。
 err = png.Encode(target, grayScale)
 if err != nil {
  log.Fatal(err)
 }
 return true
}

// 彩色轉灰度。
func formatGray(input color.Color) color.Color {
 rr, gg, bb, _ := input.RGBA()
        // 注意,1. 不是(R + G + B)/3; 2. 未對alpha進行處理。
 r := math.Pow(float64(rr), 2.2)
 g := math.Pow(float64(gg), 2.2)
 b := math.Pow(float64(bb), 2.2)
 m := math.Pow(0.2125*r+0.7154*g+0.0721*b, 1/2.2)
 Y := uint16(m + 0.5)
 bit := uint8(Y >> 8)
 bit = simplifyGray(bit)
 grayColor := color.Gray{bit}
 return grayColor
}

// 簡化灰度爲5階。
func simplifyGray(i uint8) uint8 {
 if i > 224 {
  return 255
 }
 if i > 192 {
  return 224
 }
 if i > 160 {
  return 192
 }
 if i > 128 {
  return 160
 }
 return 0
}

三、Mac 中圖片集轉 PDF。

在 Mac 裏將圖片集轉爲 PDF,比較方便。

轉自:

zhuanlan.zhihu.com/p/112393604

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Sn9W1z0UoSYeV4NkVcyqHw