-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimage.go
More file actions
94 lines (83 loc) · 2.29 KB
/
Copy pathimage.go
File metadata and controls
94 lines (83 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
"bytes"
"encoding/binary"
"image"
"image/jpeg"
_ "image/png"
"os"
"path/filepath"
"strings"
_ "golang.org/x/image/bmp"
"golang.org/x/image/draw"
)
func findImage(dir string) (string, string) {
imageExts := map[string]bool{".png": true, ".jpg": true, ".jpeg": true, ".bmp": true}
entries, err := os.ReadDir(dir)
if err != nil {
return "", ""
}
for _, e := range entries {
if e.IsDir() {
continue
}
ext := strings.ToLower(filepath.Ext(e.Name()))
if imageExts[ext] {
return filepath.Join(dir, e.Name()), ext
}
}
return "", ""
}
func convertCoverImage(srcPath, dstPath string) error {
f, err := os.Open(srcPath)
if err != nil {
return err
}
defer f.Close()
src, _, err := image.Decode(f)
if err != nil {
return err
}
// Resize to fit within 200x200
dst := image.NewRGBA(image.Rect(0, 0, 200, 200))
draw.CatmullRom.Scale(dst, dst.Bounds(), src, src.Bounds(), draw.Over, nil)
// Encode as JPEG at quality 80
var buf bytes.Buffer
if err := jpeg.Encode(&buf, dst, &jpeg.Options{Quality: 80}); err != nil {
return err
}
// Build JFIF APP0 marker for 72 DPI
jpegData := buf.Bytes()
var out bytes.Buffer
out.Write(jpegData[:2]) // SOI marker (FF D8)
// JFIF APP0 segment: FF E0 + 16-byte payload
var app0 [20]byte
app0[0] = 0xFF
app0[1] = 0xE0
binary.BigEndian.PutUint16(app0[2:4], 16) // length (includes length field but not marker)
copy(app0[4:9], "JFIF\x00") // identifier
app0[9] = 1 // major version
app0[10] = 1 // minor version
app0[11] = 1 // units: dots per inch
binary.BigEndian.PutUint16(app0[12:14], 72) // X density
binary.BigEndian.PutUint16(app0[14:16], 72) // Y density
app0[16] = 0 // thumbnail width
app0[17] = 0 // thumbnail height
out.Write(app0[:18])
// Skip existing JFIF/EXIF APP0/APP1 markers if present
i := 2
for i < len(jpegData)-1 {
if jpegData[i] != 0xFF {
break
}
marker := jpegData[i+1]
if marker == 0xE0 || marker == 0xE1 { // APP0 or APP1
segLen := int(binary.BigEndian.Uint16(jpegData[i+2 : i+4]))
i += 2 + segLen
continue
}
break
}
out.Write(jpegData[i:])
return os.WriteFile(dstPath, out.Bytes(), 0644)
}