Compare commits
	
		
			1 Commits
		
	
	
		
			1634f1bc5f
			...
			feature/im
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e2ebb2ad75 | 
							
								
								
									
										29
									
								
								image/define.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								image/define.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
// Package image ...
 | 
			
		||||
//
 | 
			
		||||
// Description : image ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2021-11-29 2:27 下午
 | 
			
		||||
package image
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// TypeGIF ...
 | 
			
		||||
	TypeGIF = "gif"
 | 
			
		||||
	// TypePNG ...
 | 
			
		||||
	TypePNG = "png"
 | 
			
		||||
	// TypeJPG ...
 | 
			
		||||
	TypeJPG = "jpg"
 | 
			
		||||
	// TypeJPEG ...
 | 
			
		||||
	TypeJPEG = "jpeg"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ImgInfo ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2:45 下午 2021/11/29
 | 
			
		||||
type ImgInfo struct {
 | 
			
		||||
	Path string
 | 
			
		||||
	Type string
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										195
									
								
								image/gif.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								image/gif.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,195 @@
 | 
			
		||||
// Package image ...
 | 
			
		||||
//
 | 
			
		||||
// Description : GIF相关操作
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2021-11-29 12:43 下午
 | 
			
		||||
package image
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"image"
 | 
			
		||||
	"image/color"
 | 
			
		||||
	"image/color/palette"
 | 
			
		||||
	"image/draw"
 | 
			
		||||
	"image/gif"
 | 
			
		||||
	"image/jpeg"
 | 
			
		||||
	"image/png"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"git.zhangdeman.cn/zhangdeman/gopkg/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// GIF ...
 | 
			
		||||
	GIF *GIFConvert
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	GIF = &GIFConvert{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GIFConvert gif转换
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 12:44 下午 2021/11/29
 | 
			
		||||
type GIFConvert struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Generate 生成
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2:13 下午 2021/11/29
 | 
			
		||||
func (g *GIFConvert) Generate(sourceImageList []string, savePath string) error {
 | 
			
		||||
	if len(sourceImageList) == 0 {
 | 
			
		||||
		return errors.New("source image list is empty")
 | 
			
		||||
	}
 | 
			
		||||
	var (
 | 
			
		||||
		err           error
 | 
			
		||||
		formatImgList []ImgInfo
 | 
			
		||||
		disposals     []byte
 | 
			
		||||
		images        []*image.Paletted
 | 
			
		||||
		// 播放速度设置 , 100 次多少秒
 | 
			
		||||
		delays []int
 | 
			
		||||
	)
 | 
			
		||||
	if formatImgList, err = g.checkImageType(sourceImageList); nil != err {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, imgInfo := range formatImgList {
 | 
			
		||||
		img, gErr := g.loadImage(imgInfo)
 | 
			
		||||
		if nil != gErr {
 | 
			
		||||
			return gErr
 | 
			
		||||
		}
 | 
			
		||||
		cp := g.getPalette(img)
 | 
			
		||||
		//cp:=append(palette.WebSafe,color.Transparent)
 | 
			
		||||
		disposals = append(disposals, gif.DisposalBackground) //透明图片需要设置
 | 
			
		||||
		p := image.NewPaletted(image.Rect(0, 0, 640, 996), cp)
 | 
			
		||||
		draw.Draw(p, p.Bounds(), img, image.ZP, draw.Src)
 | 
			
		||||
		images = append(images, p)
 | 
			
		||||
		delays = append(delays, 100)
 | 
			
		||||
	}
 | 
			
		||||
	gifInstance := &gif.GIF{
 | 
			
		||||
		Image:     images,
 | 
			
		||||
		Delay:     delays,
 | 
			
		||||
		LoopCount: -1,
 | 
			
		||||
		Disposal:  disposals,
 | 
			
		||||
	}
 | 
			
		||||
	f, fErr := os.Create(savePath)
 | 
			
		||||
	if fErr != nil {
 | 
			
		||||
		return fErr
 | 
			
		||||
	}
 | 
			
		||||
	defer func() { _ = f.Close() }()
 | 
			
		||||
	return gif.EncodeAll(f, gifInstance)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkImageType 检测图片类型
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2:16 下午 2021/11/29
 | 
			
		||||
func (g *GIFConvert) checkImageType(sourceImageList []string) ([]ImgInfo, error) {
 | 
			
		||||
	result := make([]ImgInfo, 0)
 | 
			
		||||
	for _, item := range sourceImageList {
 | 
			
		||||
		imgType := util.GetFileType(item)
 | 
			
		||||
		if len(imgType) == 0 {
 | 
			
		||||
			return result, errors.New(item + " parse img type fail!")
 | 
			
		||||
		}
 | 
			
		||||
		result = append(result, ImgInfo{
 | 
			
		||||
			Path: item,
 | 
			
		||||
			Type: imgType,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return result, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// loadImage 加载图片内容
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2:52 下午 2021/11/29
 | 
			
		||||
func (g *GIFConvert) loadImage(imgInfo ImgInfo) (image.Image, error) {
 | 
			
		||||
	var (
 | 
			
		||||
		err error
 | 
			
		||||
		f   *os.File
 | 
			
		||||
	)
 | 
			
		||||
	if f, err = os.Open(imgInfo.Path); nil != err {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer func() {
 | 
			
		||||
		_ = f.Close()
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	switch imgInfo.Type {
 | 
			
		||||
	case TypePNG:
 | 
			
		||||
		if img, imgErr := png.Decode(f); nil != err {
 | 
			
		||||
			return nil, imgErr
 | 
			
		||||
		} else {
 | 
			
		||||
			return img, nil
 | 
			
		||||
		}
 | 
			
		||||
	case TypeJPEG:
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case TypeJPG:
 | 
			
		||||
		if img, imgErr := jpeg.Decode(f); nil != err {
 | 
			
		||||
			return nil, imgErr
 | 
			
		||||
		} else {
 | 
			
		||||
			return img, nil
 | 
			
		||||
		}
 | 
			
		||||
	case TypeGIF:
 | 
			
		||||
		if img, imgErr := gif.Decode(f); nil != err {
 | 
			
		||||
			return nil, imgErr
 | 
			
		||||
		} else {
 | 
			
		||||
			return img, nil
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, errors.New(imgInfo.Type + " is not support!")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getPalette ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 3:01 下午 2021/11/29
 | 
			
		||||
func (g *GIFConvert) getPalette(m image.Image) color.Palette {
 | 
			
		||||
	p := color.Palette{color.RGBA{0x00, 0x00, 0x00, 0x00}}
 | 
			
		||||
	p9 := color.Palette(palette.Plan9)
 | 
			
		||||
	b := m.Bounds()
 | 
			
		||||
	black := false
 | 
			
		||||
	for y := b.Min.Y; y < b.Max.Y; y++ {
 | 
			
		||||
		for x := b.Min.X; x < b.Max.X; x++ {
 | 
			
		||||
			c := m.At(x, y)
 | 
			
		||||
			cc := p9.Convert(c)
 | 
			
		||||
			if cc == p9[0] {
 | 
			
		||||
				black = true
 | 
			
		||||
			}
 | 
			
		||||
			if g.isInPalette(p, cc) == -1 {
 | 
			
		||||
				p = append(p, cc)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(p) < 256 && black == true {
 | 
			
		||||
		p[0] = color.RGBA{0x00, 0x00, 0x00, 0x00} // transparent
 | 
			
		||||
		p = append(p, p9[0])
 | 
			
		||||
	}
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isInPalette ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 3:01 下午 2021/11/29
 | 
			
		||||
func (g *GIFConvert) isInPalette(p color.Palette, c color.Color) int {
 | 
			
		||||
	ret := -1
 | 
			
		||||
	for i, v := range p {
 | 
			
		||||
		if v == c {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								image/gif_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								image/gif_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
// Package image ...
 | 
			
		||||
//
 | 
			
		||||
// Description : image ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2021-11-29 3:10 下午
 | 
			
		||||
package image
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TestGIFConvert_Generate ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 3:10 下午 2021/11/29
 | 
			
		||||
func TestGIFConvert_Generate(t *testing.T) {
 | 
			
		||||
	sourceImgList := []string{"./test/1.jpeg", "./test/2.jpeg", "./test/3.jpeg", "./test/4.jpeg"}
 | 
			
		||||
	savePath := "./test/test.gif"
 | 
			
		||||
	fmt.Println(GIF.Generate(sourceImgList, savePath))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								image/test/1.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								image/test/1.jpeg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 153 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								image/test/2.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								image/test/2.jpeg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 192 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								image/test/3.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								image/test/3.jpeg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 142 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								image/test/4.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								image/test/4.jpeg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 826 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								image/test/test.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								image/test/test.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 404 KiB  | 
							
								
								
									
										13
									
								
								util/file.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								util/file.go
									
									
									
									
									
								
							@ -85,3 +85,16 @@ func IsFileExist(filePath string) (bool, bool) {
 | 
			
		||||
	f, err := os.Stat(filePath)
 | 
			
		||||
	return nil == err || os.IsExist(err), (nil == err || os.IsExist(err)) && !f.IsDir()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetFileType 获取文件类型
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2:30 下午 2021/11/29
 | 
			
		||||
func GetFileType(fileName string) string {
 | 
			
		||||
	fileArr := strings.Split(fileName, ".")
 | 
			
		||||
	if len(fileArr) < 2 {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	return strings.ToLower(fileArr[len(fileArr)-1])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user