mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
1 parent
197521edb8
commit
e20167bc3a
3 files changed
+111
-14
No files matched your search
@@ -9,7 +9,7 @@ require (
|
||||
github.com/tdewolff/canvas v0.0.0-20260923214215-09804640d00c
|
||||
github.com/tdewolff/font v0.0.0-20260913163313-54f98bb59ee6
|
||||
github.com/xiaoqidun/jbig2 v1.1.1
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20260927160712-be47f27aa7ac
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20260928042613-c4f5292e5344
|
||||
golang.org/x/crypto v0.57.0
|
||||
golang.org/x/image v0.46.0
|
||||
golang.org/x/text v0.42.0
|
||||
|
||||
@@ -62,8 +62,8 @@ github.com/tdewolff/test v1.0.12 h1:7F21DqIajswxuche0geHdrUZRCWE4oko4b7bcmkkrxk=
|
||||
github.com/tdewolff/test v1.0.12/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
||||
github.com/xiaoqidun/jbig2 v1.1.1 h1:SjliS9ZO0e9HX5oYUfBuXrfFsXhWricrSz+XY4zORDI=
|
||||
github.com/xiaoqidun/jbig2 v1.1.1/go.mod h1:8QonVWtENmh2kc6l+leqeGl7psb79DWlHDkCpdChjfQ=
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20260927160712-be47f27aa7ac h1:RLwc4JpZm5PU9vBrMffyvdubmy7u3hknjsAId9gMvB4=
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20260927160712-be47f27aa7ac/go.mod h1:4Pf0JO0BEf1uzRY+uZjlMjN/OPn3PYa0YMi6cqPPTLQ=
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20260928042613-c4f5292e5344 h1:MxA6FBXKannnXdF7f+Zo/QCiiY1vHWodKxq/rwgDT1I=
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20260928042613-c4f5292e5344/go.mod h1:4Pf0JO0BEf1uzRY+uZjlMjN/OPn3PYa0YMi6cqPPTLQ=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA=
|
||||
|
||||
+108
-11
@@ -570,17 +570,26 @@ func pdfCompositeOver(backdrop *pdfCompositePixel, source [4]float64, alpha floa
|
||||
return nil
|
||||
}
|
||||
combined := alpha + backdrop.alpha*(1-alpha)
|
||||
nonseparable := mode == "Hue" || mode == "Saturation" || mode == "Color" || mode == "Luminosity"
|
||||
var blend [4]float64
|
||||
if nonseparable {
|
||||
blend = pdfNonseparableBlend(backdrop.values, source, space, mode)
|
||||
}
|
||||
for i := 0; i < space.Components(); i++ {
|
||||
b, s := backdrop.values[i], source[i]
|
||||
if space.Model == "DeviceCMYK" {
|
||||
b, s = 1-b, 1-s
|
||||
}
|
||||
mixed, err := pdfSeparableBlend(b, s, mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if space.Model == "DeviceCMYK" {
|
||||
mixed = 1 - mixed
|
||||
mixed := blend[i]
|
||||
if !nonseparable {
|
||||
b, s := backdrop.values[i], source[i]
|
||||
if space.Model == "DeviceCMYK" {
|
||||
b, s = 1-b, 1-s
|
||||
}
|
||||
var err error
|
||||
mixed, err = pdfSeparableBlend(b, s, mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if space.Model == "DeviceCMYK" {
|
||||
mixed = 1 - mixed
|
||||
}
|
||||
}
|
||||
backdrop.values[i] = math.Max(0, math.Min(1, ((1-alpha)*backdrop.alpha*backdrop.values[i]+alpha*((1-backdrop.alpha)*source[i]+backdrop.alpha*mixed))/combined))
|
||||
}
|
||||
@@ -589,6 +598,94 @@ func pdfCompositeOver(backdrop *pdfCompositePixel, source [4]float64, alpha floa
|
||||
return nil
|
||||
}
|
||||
|
||||
// pdfNonseparableBlend 按PDF非分离混合规则计算颜色,CMYK黑版独立取值
|
||||
// 入参: b 背景颜色, s 源颜色, space 混合空间, mode 混合模式
|
||||
// 返回: [4]float64 混合分量
|
||||
func pdfNonseparableBlend(b, s [4]float64, space *pdfgo.ColorSpace, mode pdfgo.Name) [4]float64 {
|
||||
if space.Model == "DeviceGray" {
|
||||
if mode == "Luminosity" {
|
||||
return s
|
||||
}
|
||||
return b
|
||||
}
|
||||
if space.Model == "DeviceCMYK" {
|
||||
for i := 0; i < 3; i++ {
|
||||
b[i], s[i] = 1-b[i], 1-s[i]
|
||||
}
|
||||
}
|
||||
result := b
|
||||
switch mode {
|
||||
case "Hue":
|
||||
result = pdfSetLuminosity(pdfSetSaturation(s, pdfSaturation(b)), pdfLuminosity(b))
|
||||
case "Saturation":
|
||||
result = pdfSetLuminosity(pdfSetSaturation(b, pdfSaturation(s)), pdfLuminosity(b))
|
||||
case "Color":
|
||||
result = pdfSetLuminosity(s, pdfLuminosity(b))
|
||||
case "Luminosity":
|
||||
result = pdfSetLuminosity(b, pdfLuminosity(s))
|
||||
}
|
||||
if space.Model == "DeviceCMYK" {
|
||||
for i := 0; i < 3; i++ {
|
||||
result[i] = 1 - result[i]
|
||||
}
|
||||
result[3] = b[3]
|
||||
if mode == "Luminosity" {
|
||||
result[3] = s[3]
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// pdfLuminosity 计算非分离混合使用的亮度
|
||||
// 入参: c 加色分量
|
||||
// 返回: float64 亮度
|
||||
func pdfLuminosity(c [4]float64) float64 { return .3*c[0] + .59*c[1] + .11*c[2] }
|
||||
|
||||
// pdfSaturation 计算非分离混合使用的饱和度
|
||||
// 入参: c 加色分量
|
||||
// 返回: float64 饱和度
|
||||
func pdfSaturation(c [4]float64) float64 {
|
||||
return math.Max(c[0], math.Max(c[1], c[2])) - math.Min(c[0], math.Min(c[1], c[2]))
|
||||
}
|
||||
|
||||
// pdfSetSaturation 保持分量顺序并调整饱和度
|
||||
// 入参: c 加色分量, saturation 目标饱和度
|
||||
// 返回: [4]float64 调整后分量
|
||||
func pdfSetSaturation(c [4]float64, saturation float64) [4]float64 {
|
||||
minimum := math.Min(c[0], math.Min(c[1], c[2]))
|
||||
span := pdfSaturation(c)
|
||||
for i := 0; i < 3; i++ {
|
||||
if span == 0 {
|
||||
c[i] = 0
|
||||
} else {
|
||||
c[i] = (c[i] - minimum) * saturation / span
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// pdfSetLuminosity 调整亮度并按PDF ClipColor规则压缩超界分量
|
||||
// 入参: c 加色分量, luminosity 目标亮度
|
||||
// 返回: [4]float64 调整后分量
|
||||
func pdfSetLuminosity(c [4]float64, luminosity float64) [4]float64 {
|
||||
delta := luminosity - pdfLuminosity(c)
|
||||
for i := 0; i < 3; i++ {
|
||||
c[i] += delta
|
||||
}
|
||||
minimum, maximum := math.Min(c[0], math.Min(c[1], c[2])), math.Max(c[0], math.Max(c[1], c[2]))
|
||||
if minimum < 0 {
|
||||
for i := 0; i < 3; i++ {
|
||||
c[i] = luminosity + (c[i]-luminosity)*luminosity/(luminosity-minimum)
|
||||
}
|
||||
}
|
||||
if maximum > 1 {
|
||||
for i := 0; i < 3; i++ {
|
||||
c[i] = luminosity + (c[i]-luminosity)*(1-luminosity)/(maximum-luminosity)
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// pdfSeparableBlend 计算标准可分离混合函数
|
||||
// 入参: b 背景分量, s 源分量, mode 混合模式
|
||||
// 返回: float64 混合分量, error 未支持的模式
|
||||
@@ -644,6 +741,6 @@ func pdfSeparableBlend(b, s float64, mode pdfgo.Name) (float64, error) {
|
||||
case "Exclusion":
|
||||
return b + s - 2*b*s, nil
|
||||
default:
|
||||
return 0, &pdfgo.UnsupportedError{Feature: "nonseparable blend mode " + string(mode)}
|
||||
return 0, &pdfgo.UnsupportedError{Feature: "blend mode " + string(mode)}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user