forked from Quanwei1992/ebookdownloader
-
Notifications
You must be signed in to change notification settings - Fork 12
/
ebookCover.go
158 lines (136 loc) · 4.44 KB
/
ebookCover.go
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package ebookdownloader
import (
"context"
"errors"
"fmt"
"image"
"image/draw"
"image/jpeg"
"io"
"log"
"net/http"
"os"
"path/filepath"
"time"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/chromedp"
"github.com/goki/freetype"
)
const (
fontSize = 40 //字体尺寸
)
// GenerateCover 生成封面 cover.jpg
func (this BookInfo) GenerateCover() error {
//需要添加内容的图片
coverAbs, _ := filepath.Abs("./cover.jpg")
//fmt.Println(coverAbs)
imgfile, err := os.Create(coverAbs)
if err != nil {
fmt.Println(err.Error())
return err
}
defer imgfile.Close()
img := image.NewNRGBA(image.Rect(0, 0, 617, 822))
fg, bg := image.Black, image.White
//需要一个ttf字体文件
//fontAbs, _ := filepath.Abs("./fonts/WenQuanYiMicroHei.ttf")
fontBytes, _ := fontFS.ReadFile("fonts/WenQuanYiMicroHei.ttf")
if err != nil {
log.Println(err.Error())
return err
}
font, err := freetype.ParseFont(fontBytes)
if err != nil {
log.Println(err.Error())
return err
}
draw.Draw(img, img.Bounds(), bg, image.ZP, draw.Src)
f := freetype.NewContext()
f.SetDPI(72)
f.SetFont(font)
f.SetFontSize(fontSize)
f.SetClip(img.Bounds())
f.SetDst(img)
f.SetSrc(fg) //设置字体颜色
pt := freetype.Pt(img.Bounds().Dx()-370, img.Bounds().Dy()-590) //字体出现的位置
//尝试把字符串,坚着写入图片中
NameRune := []rune(this.Name)
f.DrawString(string(NameRune[0]), pt) // 第一个中文字符
for index := 1; index < len(NameRune); index++ {
pt.Y += f.PointToFixed(50)
f.DrawString(string(NameRune[index]), pt) //写入 小说名
}
f.SetFontSize(35) //重新设置 字体大小为35
ptAuthor := freetype.Pt(img.Bounds().Dx()-320, img.Bounds().Dy()-500) //字体出现的位置
f.DrawString(this.Author+" ©著", ptAuthor) //写入小说作者名
err = jpeg.Encode(imgfile, img, &jpeg.Options{Quality: 100})
if err != nil {
fmt.Println(err.Error())
return err
}
return nil
}
// DownloadCoverImage 下载小说的封面图片
func (this BookInfo) DownloadCoverImage(coverURL string) error {
res, err := http.Get(coverURL)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
fmt.Printf("封面地址[%s]下载失败,改为直接生成封面!\n", coverURL)
this.GenerateCover()
//直接在此处结束进程,返回到上级进程中
return errors.New("封面下载失败,改为直接生成封面")
}
body, err := io.ReadAll(res.Body)
if err != nil {
fmt.Printf("封面地址[%s]下载失败,改为直接生成封面!\n", coverURL)
this.GenerateCover()
//直接在此处结束进程,返回到上级进程中
return err
}
//使用
newCoverpath, _ := filepath.Abs("./cover.jpg")
os.WriteFile(newCoverpath, body, 0666)
return nil
}
// GetCover 主要用于从 起点中文网上提取小说的封面
func (this BookInfo) GetCover() error {
if this.DlCoverFromWeb != true {
return this.GenerateCover()
}
options := []chromedp.ExecAllocatorOption{
//chromedp.Flag("headless", false), // debug使用
chromedp.Flag("blink-settings", "imagesEnabled=false"),
chromedp.UserAgent(`Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36`),
}
options = append(chromedp.DefaultExecAllocatorOptions[:], options...)
c, _ := chromedp.NewExecAllocator(context.Background(), options...)
// create context
chromeCtx, cancel := chromedp.NewContext(c)
// 执行一个空task, 用提前创建Chrome实例
chromedp.Run(chromeCtx, make([]chromedp.Action, 0, 1)...)
timeoutCtx, cancel := context.WithTimeout(chromeCtx, 20*time.Second)
defer cancel()
var nodes []*cdp.Node
searchLink := "https://www.qidian.com/search?kw=" + this.Name
err := chromedp.Run(timeoutCtx,
chromedp.Navigate(searchLink),
chromedp.WaitVisible(`div[id="result-list"]`),
chromedp.Nodes("//div[@id='result-list']//div[@class='book-img-text']//ul//li[1]//div[@class='book-img-box']//a//img", &nodes),
)
//当执行出错的时候,优化执行生成封面,再返回错误信息
if err != nil {
this.GenerateCover()
return err
}
//当执行出错的时候,优化执行生成封面,再返回错误信息
if len(nodes) < 1 {
this.GenerateCover()
return errors.New("无法获取到封面地址,或者小说名字错误!")
}
CoverURL := "https:" + nodes[0].AttributeValue("src")
//到最后返回nil
return this.DownloadCoverImage(CoverURL)
}