Skip to content

Commit

Permalink
优化图片处理
Browse files Browse the repository at this point in the history
  • Loading branch information
fesiong committed Mar 13, 2024
1 parent 5f43c07 commit 3a1fcd3
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 1 deletion.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# 更新日志

## v3.3.3 `anqicms` `2024-03-13`

- [优化] API接口文档列表和文档详情增加支持待审文档显示
- [优化] 如果原JPEG图片的质量低于预设值,则使用原质量值
- [修复] 修复伪静态规则使用多级分类时候内存暴涨的问题
- [修复] 修复伪静态规则对时间支持不全面的问题
- [修复] 修复后台蜘蛛统计存在标记错误的问题
- [修复] 后台界面调整

## v3.3.2 `anqicms` `2024-03-10`

- [新增] 增加 Google Indexing
Expand Down
2 changes: 1 addition & 1 deletion config/constant.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package config

const Version = "3.3.2"
const Version = "3.3.3"

const (
StatusOK = 0
Expand Down
32 changes: 32 additions & 0 deletions controller/manageController/pluginSendmail.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/kataras/iris/v12"
"kandaoni.com/anqicms/config"
"kandaoni.com/anqicms/provider"
"kandaoni.com/anqicms/request"
)

func PluginSendmailList(ctx iris.Context) {
Expand Down Expand Up @@ -36,6 +37,37 @@ func PluginSendmailTest(ctx iris.Context) {
})
return
}
var req request.PluginTestSendmailRequest
if err := ctx.ReadJSON(&req); err != nil {
ctx.JSON(iris.Map{
"code": config.StatusFailed,
"msg": err.Error(),
})
return
}

if req.Recipient != "" {
if req.Subject == "" || req.Message == "" {
ctx.JSON(iris.Map{
"code": config.StatusFailed,
"msg": "请填写回复标题和内容",
})
return
}
err := currentSite.SendMail(req.Subject, req.Message, req.Recipient)
if err != nil {
ctx.JSON(iris.Map{
"code": config.StatusFailed,
"msg": err.Error(),
})
return
}
ctx.JSON(iris.Map{
"code": config.StatusOK,
"msg": "邮件发送成功",
})
return
}

subject := "测试邮件"
content := "这是一封测试邮件。收到邮件表示配置正常"
Expand Down
221 changes: 221 additions & 0 deletions library/image.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package library

import (
"bytes"
"encoding/hex"
"errors"
"github.com/disintegration/imaging"
"image"
"image/color"
"image/draw"
"io"
"strings"
)

Expand Down Expand Up @@ -62,3 +65,221 @@ func HEXToRGB(h string) color.Color {
}
return color.RGBA{R: bs[0], G: bs[1], B: bs[2], A: 255}
}

// Errors
var (
ErrInvalidJPEG = errors.New("Invalid JPEG header")
ErrWrongTable = errors.New("ERROR: Wrong size for quantization table")
ErrShortSegment = errors.New("short segment length")
ErrShortDQT = errors.New("DQT section too short")
)

const (
//from /usr/lib/go/src/image/jpeg/reader.go
dqtMarker = 0xdb // Define Quantization Table.
)

// for the DQT marker -- start --
// Sample quantization tables from JPEG spec --- only needed for
// guesstimate of quality factor. Note these are in zigzag order.

var stdLuminanceQuantTbl = [64]int{
16, 11, 12, 14, 12, 10, 16, 14,
13, 14, 18, 17, 16, 19, 24, 40,
26, 24, 22, 22, 24, 49, 35, 37,
29, 40, 58, 51, 61, 60, 57, 51,
56, 55, 64, 72, 92, 78, 64, 68,
87, 69, 55, 56, 80, 109, 81, 87,
95, 98, 103, 104, 103, 62, 77, 113,
121, 112, 100, 120, 92, 101, 103, 99,
}

var stdChrominanceQuantTbl = [64]int{
17, 18, 18, 24, 21, 24, 47, 26,
26, 47, 99, 66, 56, 66, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
}

var deftabs = [2][64]int{
stdLuminanceQuantTbl, stdChrominanceQuantTbl,
}

// for the DQT marker -- end --

// Qualitier ...
type Qualitier interface {
Quality() int
}

type jpegReader struct {
rs io.ReadSeeker
q int
}

// NewQualityWithBytes ...
func NewQualityWithBytes(buf []byte) (qr Qualitier, err error) {
return NewQuality(bytes.NewReader(buf))
}

// NewQuality ...
func NewQuality(rs io.ReadSeeker) (qr Qualitier, err error) {
jr := &jpegReader{rs: rs}
_, err = jr.rs.Seek(0, 0)
if err != nil {
return
}

var (
sign = make([]byte, 2)
)
_, err = jr.rs.Read(sign)
if err != nil {
return
}
if sign[0] != 0xff && sign[1] != 0xd8 {
err = ErrInvalidJPEG
return
}

jr.q, err = jr.readQuality()
if err != nil {
return
}
qr = jr
return
}

func (jr *jpegReader) readQuality() (q int, err error) {
for {
mark := jr.readMarker()
if mark == 0 {
err = ErrInvalidJPEG
return
}
var (
length, tableindex int
sign = make([]byte, 2)
)
_, err = jr.rs.Read(sign)
if err != nil {
return
}

length = int(sign[0])<<8 + int(sign[1]) - 2
if length < 0 {
err = ErrShortSegment
return
}

if (mark & 0xff) != dqtMarker { // not a quantization table
_, err = jr.rs.Seek(int64(length), 1)
if err != nil {
return
}
continue
}

if length%65 != 0 {
err = ErrWrongTable
return
}

var tabuf = make([]byte, length)
var n int
n, err = jr.rs.Read(tabuf)
if err != nil {
return
}

allones := 1
var cumsf, cumsf2 float64
buf := tabuf[0:n]

var reftable [64]int

a := 0
for a < n {
tableindex = int(tabuf[a] & 0x0f)
a++
//precision: (c>>4) ? 16 : 8

if tableindex < 2 {
reftable = deftabs[tableindex]
}
// Read in the table, compute statistics relative to reference table
if a+64 > n {
err = ErrShortDQT
return
}
for coefindex := 0; coefindex < 64 && a < n; coefindex++ {
var val int

if tableindex>>4 != 0 {
temp := int(buf[a])
a++
temp *= 256
val = int(buf[a]) + temp
a++
} else {
val = int(buf[a])
a++
}

// scaling factor in percent
x := 100.0 * float64(val) / float64(reftable[coefindex])
cumsf += x
cumsf2 += x * x
// separate check for all-ones table (Q 100)
if val != 1 {
allones = 0
}
}

if 0 != len(reftable) { // terse output includes quality
var qual float64
cumsf /= 64.0 // mean scale factor
cumsf2 /= 64.0
if allones == 1 { // special case for all-ones table
qual = 100.0
} else if cumsf <= 100.0 {
qual = (200.0 - cumsf) / 2.0
} else {
qual = 5000.0 / cumsf
}

if tableindex == 0 {
q = (int)(qual + 0.5)
return
}
}
}

}
}

func (jr *jpegReader) readMarker() int {
var (
mark = make([]byte, 2)
err error
)

ReadAgain:
_, err = jr.rs.Read(mark)
if err != nil {
return 0
}
if mark[0] != 0xff || mark[1] == 0xff || mark[1] == 0x00 {
goto ReadAgain
}

return int(mark[0])<<8 + int(mark[1])
}

func (jr *jpegReader) Quality() int {
return jr.q
}
16 changes: 16 additions & 0 deletions provider/attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ func (w *Website) AttachmentUpload(file multipart.File, info *multipart.FileHead
if fileExt == ".jpeg" {
fileExt = ".jpg"
}
if fileExt == ".ico" || fileExt == ".bmp" {
fileExt = ".png"
}
if fileExt == "." {
fileExt = ""
}
Expand Down Expand Up @@ -151,6 +154,10 @@ func (w *Website) AttachmentUpload(file multipart.File, info *multipart.FileHead
if imgType == "jpeg" {
imgType = "jpg"
}
oriImgType := imgType
if imgType == "ico" || imgType == "bmp" {
imgType = "png"
}
//只允许上传jpg,jpeg,gif,png,webp
if imgType != "jpg" && imgType != "jpeg" && imgType != "gif" && imgType != "png" && imgType != "webp" {
return nil, errors.New(fmt.Sprintf("%s: %s。", w.Lang("不支持的图片格式"), imgType))
Expand All @@ -175,6 +182,15 @@ func (w *Website) AttachmentUpload(file multipart.File, info *multipart.FileHead
// 默认质量是90
quality = webp.DefaulQuality
}
if oriImgType == "jpg" {
j, err2 := library.NewQuality(file)
file.Seek(0, 0)
if err2 == nil {
if j.Quality() < quality {
quality = j.Quality()
}
}
}

if w.Content.ResizeImage == 1 && width > resizeWidth && imgType != "gif" {
img = library.Resize(img, resizeWidth, 0)
Expand Down
6 changes: 6 additions & 0 deletions request/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,9 @@ type PluginHtmlCachePushRequest struct {
All bool `json:"all"`
Paths []string `json:"paths"`
}

type PluginTestSendmailRequest struct {
Recipient string `json:"recipient"`
Subject string `json:"subject"`
Message string `json:"message"`
}

0 comments on commit 3a1fcd3

Please sign in to comment.