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)
 | 
						f, err := os.Stat(filePath)
 | 
				
			||||||
	return nil == err || os.IsExist(err), (nil == err || os.IsExist(err)) && !f.IsDir()
 | 
						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