mirror of
https://github.com/gen2brain/cbconvert
synced 2025-10-13 18:18:52 +02:00
Remove levels
This commit is contained in:
40
README.md
40
README.md
@@ -64,8 +64,8 @@ This is what it looks like in the PCManFM file manager:
|
||||
Best fit for required width and height (default "false")
|
||||
--format
|
||||
Image format, valid values are jpeg, png, tiff, bmp, webp, avif, jxl (default "jpeg")
|
||||
--archive
|
||||
Archive format, valid values are zip, tar (default "zip")
|
||||
--archive
|
||||
Archive format, valid values are zip, tar (default "zip")
|
||||
--quality
|
||||
Image quality (default "75")
|
||||
--filter
|
||||
@@ -77,7 +77,7 @@ This is what it looks like in the PCManFM file manager:
|
||||
--no-nonimage
|
||||
Remove non-image files from the archive (default "false")
|
||||
--no-convert
|
||||
Do not transform or convert images (default "false")
|
||||
Do not transform or convert images (default "false")
|
||||
--grayscale
|
||||
Convert images to grayscale (monochromatic) (default "false")
|
||||
--rotate
|
||||
@@ -88,16 +88,6 @@ This is what it looks like in the PCManFM file manager:
|
||||
Adjust the contrast of the images, must be in the range (-100, 100) (default "0")
|
||||
--suffix
|
||||
Add suffix to file basename (default "")
|
||||
--levels-inmin
|
||||
Shadow input value (default "0")
|
||||
--levels-gamma
|
||||
Midpoint/Gamma (default "1")
|
||||
--levels-inmax
|
||||
Highlight input value (default "255")
|
||||
--levels-outmin
|
||||
Shadow output value (default "0")
|
||||
--levels-outmax
|
||||
Highlight output value (default "255")
|
||||
--outdir
|
||||
Output directory (default ".")
|
||||
--size
|
||||
@@ -153,19 +143,19 @@ This is what it looks like in the PCManFM file manager:
|
||||
--quiet
|
||||
Hide console output (default "false")
|
||||
|
||||
meta
|
||||
CBZ metadata
|
||||
meta
|
||||
CBZ metadata
|
||||
|
||||
--cover
|
||||
Print cover name (default "false")
|
||||
--comment
|
||||
Print zip comment (default "false")
|
||||
--comment-body
|
||||
Set zip comment (default "")
|
||||
--file-add
|
||||
Add file to archive (default "")
|
||||
--file-remove
|
||||
Remove file(s) from archive (glob pattern, i.e. *.xml) (default "")
|
||||
--cover
|
||||
Print cover name (default "false")
|
||||
--comment
|
||||
Print zip comment (default "false")
|
||||
--comment-body
|
||||
Set zip comment (default "")
|
||||
--file-add
|
||||
Add file to archive (default "")
|
||||
--file-remove
|
||||
Remove file(s) from archive (glob pattern, i.e. *.xml) (default "")
|
||||
|
||||
```
|
||||
|
||||
|
71
cbconvert.go
71
cbconvert.go
@@ -121,16 +121,6 @@ type Options struct {
|
||||
Size int
|
||||
// Hide console output
|
||||
Quiet bool
|
||||
// Shadow input value
|
||||
LevelsInMin int
|
||||
// Highlight input value
|
||||
LevelsInMax int
|
||||
// Midpoint/gamma
|
||||
LevelsGamma float64
|
||||
// Shadow output value
|
||||
LevelsOutMin int
|
||||
// Highlight output value
|
||||
LevelsOutMax int
|
||||
}
|
||||
|
||||
// Converter type.
|
||||
@@ -180,9 +170,6 @@ func NewOptions() Options {
|
||||
o.Archive = "zip"
|
||||
o.Quality = 75
|
||||
o.Filter = 2
|
||||
o.LevelsGamma = 1.0
|
||||
o.LevelsInMax = 255
|
||||
o.LevelsOutMax = 255
|
||||
|
||||
return o
|
||||
}
|
||||
@@ -487,14 +474,6 @@ func (c *Converter) imageConvert(ctx context.Context, img image.Image, index int
|
||||
|
||||
img = c.imageTransform(img)
|
||||
|
||||
if c.Opts.LevelsInMin != 0 || c.Opts.LevelsInMax != 255 || c.Opts.LevelsGamma != 1.0 ||
|
||||
c.Opts.LevelsOutMin != 0 || c.Opts.LevelsOutMax != 255 {
|
||||
img, err = c.imageLevel(img)
|
||||
if err != nil {
|
||||
return fmt.Errorf("imageConvert: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
w, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("imageConvert: %w", err)
|
||||
@@ -553,48 +532,6 @@ func (c *Converter) imageTransform(img image.Image) image.Image {
|
||||
return i
|
||||
}
|
||||
|
||||
// imageLevel applies a Photoshop-like levels operation on an image.
|
||||
func (c *Converter) imageLevel(img image.Image) (image.Image, error) {
|
||||
mw := imagick.NewMagickWand()
|
||||
defer mw.Destroy()
|
||||
|
||||
rgba := imageToRGBA(img)
|
||||
err := mw.ConstituteImage(uint(img.Bounds().Dx()), uint(img.Bounds().Dy()), "RGBA", imagick.PIXEL_CHAR, rgba.Pix)
|
||||
if err != nil {
|
||||
return img, fmt.Errorf("imageLevel: %w", err)
|
||||
}
|
||||
|
||||
_, qrange := imagick.GetQuantumRange()
|
||||
quantumRange := float64(qrange)
|
||||
|
||||
inMin := (quantumRange * float64(c.Opts.LevelsInMin)) / 255
|
||||
inMax := (quantumRange * float64(c.Opts.LevelsInMax)) / 255
|
||||
outMin := (quantumRange * float64(c.Opts.LevelsOutMin)) / 255
|
||||
outMax := (quantumRange * float64(c.Opts.LevelsOutMax)) / 255
|
||||
|
||||
if err := mw.LevelImage(inMin, c.Opts.LevelsGamma, inMax); err != nil {
|
||||
return img, fmt.Errorf("imageLevel: %w", err)
|
||||
}
|
||||
|
||||
if err := mw.LevelImage(-outMin, 1.0, quantumRange+(quantumRange-outMax)); err != nil {
|
||||
return img, fmt.Errorf("imageLevel: %w", err)
|
||||
}
|
||||
|
||||
blob := mw.GetImageBlob()
|
||||
|
||||
var i image.Image
|
||||
i, err = c.imageDecode(bytes.NewReader(blob))
|
||||
if err != nil {
|
||||
e := err
|
||||
i, err = c.imDecode(bytes.NewReader(blob), "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("imageLevel: %w: %w", e, err)
|
||||
}
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// imageDecode decodes image from reader.
|
||||
func (c *Converter) imageDecode(reader io.Reader) (image.Image, error) {
|
||||
img, _, err := image.Decode(reader)
|
||||
@@ -1225,14 +1162,6 @@ func (c *Converter) Preview(fileName string, fileInfo os.FileInfo, width, height
|
||||
|
||||
i = c.imageTransform(i)
|
||||
|
||||
if c.Opts.LevelsInMin != 0 || c.Opts.LevelsInMax != 255 || c.Opts.LevelsGamma != 1.0 ||
|
||||
c.Opts.LevelsOutMin != 0 || c.Opts.LevelsOutMax != 255 {
|
||||
i, err = c.imageLevel(i)
|
||||
if err != nil {
|
||||
return img, fmt.Errorf("%s: %w", fileName, err)
|
||||
}
|
||||
}
|
||||
|
||||
var w bytes.Buffer
|
||||
|
||||
switch c.Opts.Format {
|
||||
|
@@ -120,11 +120,6 @@ func options() cbconvert.Options {
|
||||
opts.Brightness = iup.GetHandle("Brightness").GetInt("VALUE")
|
||||
opts.Contrast = iup.GetHandle("Contrast").GetInt("VALUE")
|
||||
opts.Rotate = iup.GetHandle("Rotate").GetInt("VALUESTRING")
|
||||
opts.LevelsInMin = iup.GetHandle("LevelsInMin").GetInt("VALUE")
|
||||
opts.LevelsInMax = iup.GetHandle("LevelsInMax").GetInt("VALUE")
|
||||
opts.LevelsOutMin = iup.GetHandle("LevelsOutMin").GetInt("VALUE")
|
||||
opts.LevelsOutMax = iup.GetHandle("LevelsOutMax").GetInt("VALUE")
|
||||
opts.LevelsGamma = iup.GetHandle("LevelsGamma").GetDouble("VALUE")
|
||||
|
||||
return opts
|
||||
}
|
||||
@@ -539,94 +534,6 @@ func tabs() iup.Ihandle {
|
||||
return iup.DEFAULT
|
||||
})),
|
||||
),
|
||||
iup.Vbox(
|
||||
iup.Label("Input Levels:"),
|
||||
iup.Hbox(
|
||||
iup.Text().SetAttributes(`SPIN=YES, SPINMAX=255, VALUE=0, VISIBLECOLUMNS=3, MASK="/d*"`).
|
||||
SetHandle("LevelsInMin").SetAttribute("TIP", "Min").
|
||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
||||
|
||||
return iup.DEFAULT
|
||||
})).
|
||||
SetCallback("KILLFOCUS_CB", iup.KillFocusFunc(func(ih iup.Ihandle) int {
|
||||
if ih.GetAttribute("MYVALUE") != "" {
|
||||
previewPost()
|
||||
}
|
||||
ih.SetAttribute("MYVALUE", "")
|
||||
|
||||
return iup.DEFAULT
|
||||
})),
|
||||
iup.Fill(),
|
||||
iup.Val("").SetAttributes(`VALUE=1.0, SHOWTICKS=10`).
|
||||
SetHandle("LevelsGamma").SetAttribute("TIP", "Gamma").
|
||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
||||
|
||||
return iup.DEFAULT
|
||||
})).
|
||||
SetCallback("KILLFOCUS_CB", iup.KillFocusFunc(func(ih iup.Ihandle) int {
|
||||
if ih.GetAttribute("MYVALUE") != "" {
|
||||
previewPost()
|
||||
}
|
||||
ih.SetAttribute("MYVALUE", "")
|
||||
|
||||
return iup.DEFAULT
|
||||
})),
|
||||
iup.Fill(),
|
||||
iup.Text().SetAttributes(`SPIN=YES, SPINMAX=255, VALUE=255, VISIBLECOLUMNS=3, MASK="/d*"`).
|
||||
SetHandle("LevelsInMax").SetAttribute("TIP", "Max").
|
||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
||||
|
||||
return iup.DEFAULT
|
||||
})).
|
||||
SetCallback("KILLFOCUS_CB", iup.KillFocusFunc(func(ih iup.Ihandle) int {
|
||||
if ih.GetAttribute("MYVALUE") != "" {
|
||||
previewPost()
|
||||
}
|
||||
ih.SetAttribute("MYVALUE", "")
|
||||
|
||||
return iup.DEFAULT
|
||||
})),
|
||||
).SetAttributes("ALIGNMENT=ACENTER, MAXSIZE=340x"),
|
||||
),
|
||||
iup.Vbox(
|
||||
iup.Label("Output Levels:"),
|
||||
iup.Hbox(
|
||||
iup.Text().SetAttributes(`SPIN=YES, SPINMAX=255, VALUE=0, VISIBLECOLUMNS=3, MASK="/d*"`).
|
||||
SetHandle("LevelsOutMin").SetAttribute("TIP", "Min").
|
||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
||||
|
||||
return iup.DEFAULT
|
||||
})).
|
||||
SetCallback("KILLFOCUS_CB", iup.KillFocusFunc(func(ih iup.Ihandle) int {
|
||||
if ih.GetAttribute("MYVALUE") != "" {
|
||||
previewPost()
|
||||
}
|
||||
ih.SetAttribute("MYVALUE", "")
|
||||
|
||||
return iup.DEFAULT
|
||||
})),
|
||||
iup.Fill(),
|
||||
iup.Text().SetAttributes(`SPIN=YES, SPINMAX=255, VALUE=255, VISIBLECOLUMNS=3, MASK="/d*"`).
|
||||
SetHandle("LevelsOutMax").SetAttribute("TIP", "Max").
|
||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
||||
|
||||
return iup.DEFAULT
|
||||
})).
|
||||
SetCallback("KILLFOCUS_CB", iup.KillFocusFunc(func(ih iup.Ihandle) int {
|
||||
if ih.GetAttribute("MYVALUE") != "" {
|
||||
previewPost()
|
||||
}
|
||||
ih.SetAttribute("MYVALUE", "")
|
||||
|
||||
return iup.DEFAULT
|
||||
})),
|
||||
).SetAttributes("ALIGNMENT=ACENTER, MAXSIZE=340x"),
|
||||
),
|
||||
).SetHandle("VboxTransform").SetAttributes("MARGIN=5x5, GAP=5")
|
||||
|
||||
return iup.Tabs(
|
||||
|
@@ -181,11 +181,6 @@ func parseFlags() (cbconvert.Options, []string) {
|
||||
convert.IntVar(&opts.Brightness, "brightness", 0, "Adjust the brightness of the images, must be in the range (-100, 100)")
|
||||
convert.IntVar(&opts.Contrast, "contrast", 0, "Adjust the contrast of the images, must be in the range (-100, 100)")
|
||||
convert.StringVar(&opts.Suffix, "suffix", "", "Add suffix to file basename")
|
||||
convert.IntVar(&opts.LevelsInMin, "levels-inmin", 0, "Shadow input value")
|
||||
convert.Float64Var(&opts.LevelsGamma, "levels-gamma", 1.0, "Midpoint/Gamma")
|
||||
convert.IntVar(&opts.LevelsInMax, "levels-inmax", 255, "Highlight input value")
|
||||
convert.IntVar(&opts.LevelsOutMin, "levels-outmin", 0, "Shadow output value")
|
||||
convert.IntVar(&opts.LevelsOutMax, "levels-outmax", 255, "Highlight output value")
|
||||
convert.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
|
||||
convert.IntVar(&opts.Size, "size", 0, "Process only files larger than size (in MB)")
|
||||
convert.BoolVar(&opts.Recursive, "recursive", false, "Process subdirectories recursively")
|
||||
|
Reference in New Issue
Block a user