5 Commits

Author SHA1 Message Date
Milan Nikolic 2c3fb88e7e use unarr instead of libarchive 2015-11-01 13:57:30 +01:00
Milan Nikolic 5c5352182f Update cbconvert.go 2015-10-30 11:23:02 +01:00
Milan Nikolic f490c97974 Update README.md 2015-10-30 03:07:07 +01:00
Milan Nikolic 7a0c108fd1 Update cbconvert.go 2015-10-30 03:06:48 +01:00
Milan Nikolic e819224725 Update README.md 2015-10-30 02:38:21 +01:00
2 changed files with 83 additions and 79 deletions
+12 -10
View File
@@ -20,15 +20,15 @@ Features
Download
--------
- [Windows static build](https://github.com/gen2brain/cbconvert/releases/download/0.1.0/bukanir-0.1.0.zip)
- [Linux 64bit build](https://github.com/gen2brain/cbconvert/releases/download/0.1.0/bukanir-0.1.0.tar.gz)
- [Windows static build](https://github.com/gen2brain/cbconvert/releases/download/0.1.0/cbconvert-0.1.0.zip)
- [Linux 64bit build](https://github.com/gen2brain/cbconvert/releases/download/0.1.0/cbconvert-0.1.0.tar.gz)
Compile
-------
Install poppler, poppler-glib, cairo, libarchive and imagemagick dev packages:
Install poppler, poppler-glib, cairo and imagemagick dev packages:
apt-get install libpoppler-glib-dev libcairo2-dev libarchive-dev libmagickcore-dev libmagickwand-dev
apt-get install libpoppler-glib-dev libcairo2-dev libmagickcore-dev libmagickwand-dev
Install go package:
@@ -38,9 +38,9 @@ Install go package:
Dependencies
------------
go get github.com/MStoykov/go-libarchive
go get github.com/cheggaaa/go-poppler
go get github.com/cheggaaa/pb
go get github.com/gen2brain/go-unarr
go get github.com/gographics/imagick/imagick
go get github.com/hotei/bmp
go get github.com/nfnt/resize
@@ -71,7 +71,7 @@ Using
-o, --outdir="." output directory
-m, --size=0 process only files larger then size (in MB)
-r, --recursive process subdirectories recursively
-v, --quiet hide console output
-Q, --quiet hide console output
Args:
<args> filename or directory
@@ -80,14 +80,16 @@ Using
Examples
--------
Rescale images to 1200px for all supported files found in directory with size larger then 60MB:
cbconvert --recursive --width 1200 --size 60 /media/comics/Thorgal/
Rescale images to 1200px for all supported files found in directory with size larger then 60MB.
Convert all images in archive to 4bit BMP image and save result in ~/comics directory:
cbconvert --bmp --outdir ~/comics /media/comics/Garfield/Garfield_01.cbz
Convert all images in archive to 4bit BMP image and save result in ~/comics directory. [BMP](http://en.wikipedia.org/wiki/BMP_file_format) format is uncompressed, for black&white pages very good choice. Archive size can be smaller 2-3x and file will be readable by comic readers.
[BMP](http://en.wikipedia.org/wiki/BMP_file_format) format is uncompressed, for black&white pages very good choice. Archive size can be smaller 2-3x and file will be readable by comic readers.
Generate thumbnails by freedesktop specification in ~/.thumbnails/normal directory, Lanczos3 algorithm is used for resizing:
cbconvert --interpolation=5 --outdir ~/.thumbnails/normal --thumbnail /media/comics/GrooTheWanderer/
Generate thumbnails by freedesktop specification in ~/.thumbnails/normal directory, Lanczos3 algorithm is used for resizing.
+68 -66
View File
@@ -39,9 +39,9 @@ import (
"sync"
"syscall"
"github.com/MStoykov/go-libarchive"
"github.com/cheggaaa/go-poppler"
"github.com/cheggaaa/pb"
"github.com/gen2brain/go-unarr"
"github.com/gographics/imagick/imagick"
_ "github.com/hotei/bmp"
"github.com/nfnt/resize"
@@ -199,69 +199,63 @@ func convertPDF(file string) {
func convertArchive(file string) {
workdir, _ = ioutil.TempDir(os.TempDir(), "cbc")
f, err := os.Open(file)
if err != nil {
fmt.Fprintf(os.Stderr, "Error Open: %v\n", err.Error())
return
}
defer f.Close()
ncontents := len(listArchive(file))
reader, err := archive.NewReader(f)
archive, err := unarr.NewArchive(file)
if err != nil {
fmt.Fprintf(os.Stderr, "Error NewReader: %v\n", err.Error())
}
defer reader.Free()
defer reader.Close()
defer archive.Close()
var bar *pb.ProgressBar
if !opts.Quiet {
s, _ := f.Stat()
bar = pb.New(int(s.Size()))
bar.SetUnits(pb.U_BYTES)
bar = pb.New(ncontents)
bar.ShowTimeLeft = false
bar.Prefix(fmt.Sprintf("Converting %d of %d: ", current, nfiles))
bar.Start()
}
for {
entry, err := reader.Next()
err := archive.Entry()
if err != nil {
if err == archive.ErrArchiveEOF {
if err == io.EOF {
break
} else {
fmt.Fprintf(os.Stderr, "Error Next: %v\n", err.Error())
fmt.Fprintf(os.Stderr, "Error Entry: %v\n", err.Error())
continue
}
}
stat := entry.Stat()
if stat.Mode()&os.ModeType != 0 || stat.IsDir() {
continue
}
if !opts.Quiet {
size := reader.Size()
bar.Set(size)
bar.Increment()
}
pathname := entry.PathName()
size := archive.Size()
pathname := archive.Name()
if isImage(pathname) {
buf := new(bytes.Buffer)
_, err := buf.ReadFrom(reader)
if err != nil {
fmt.Fprintf(os.Stderr, "Error ReadFrom: %v\n", err.Error())
buf := make([]byte, size)
for size > 0 {
n, err := archive.Read(buf)
if err != nil && err != io.EOF {
break
}
size -= n
}
if size > 0 {
fmt.Printf("Error Read\n")
continue
}
img, err := decodeImage(bytes.NewReader(buf.Bytes()), pathname)
if isImage(pathname) {
img, err := decodeImage(bytes.NewReader(buf), pathname)
if err != nil {
fmt.Fprintf(os.Stderr, "Error Decode: %v\n", err.Error())
continue
}
if opts.NoRGB && !isGrayScale(img) {
copyFile(bytes.NewReader(buf.Bytes()), filepath.Join(workdir, filepath.Base(pathname)))
copyFile(bytes.NewReader(buf), filepath.Join(workdir, filepath.Base(pathname)))
continue
}
@@ -271,7 +265,7 @@ func convertArchive(file string) {
go convertImage(img, 0, pathname)
}
} else {
copyFile(reader, filepath.Join(workdir, filepath.Base(pathname)))
copyFile(bytes.NewReader(buf), filepath.Join(workdir, filepath.Base(pathname)))
}
}
wg.Wait()
@@ -368,64 +362,72 @@ func saveArchive(file string) {
z.Close()
}
// Unpacks archive to directory
func unpackArchive(file string, dir string) {
f, err := os.Open(file)
if err != nil {
fmt.Fprintf(os.Stderr, "Error Open: %v\n", err.Error())
return
}
defer f.Close()
reader, err := archive.NewReader(f)
// Lists contents of archive
func listArchive(file string) []string {
var contents []string
archive, err := unarr.NewArchive(file)
if err != nil {
fmt.Fprintf(os.Stderr, "Error NewReader: %v\n", err.Error())
return
}
defer reader.Free()
defer reader.Close()
defer archive.Close()
for {
entry, err := reader.Next()
err := archive.Entry()
if err != nil {
if err == archive.ErrArchiveEOF {
if err == io.EOF {
break
} else {
fmt.Fprintf(os.Stderr, "Error Entry: %v\n", err.Error())
continue
}
}
if entry.Stat().Mode()&os.ModeType == 0 {
err = copyFile(reader, filepath.Join(dir, entry.PathName()))
pathname := archive.Name()
contents = append(contents, pathname)
}
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err.Error())
}
}
return contents
}
// Extracts cover from archive
func coverArchive(file string) (image.Image, error) {
tmpdir, _ := ioutil.TempDir(os.TempDir(), "cbc")
defer os.RemoveAll(tmpdir)
var images []string
unpackArchive(file, tmpdir)
images := getImages(tmpdir)
if len(images) == 0 {
return nil, errors.New("No images")
contents := listArchive(file)
for _, c := range contents {
if isImage(c) {
images = append(images, c)
}
}
cover := getCover(images)
p, err := os.Open(cover)
archive, err := unarr.NewArchive(file)
if err != nil {
return nil, err
}
defer p.Close()
defer archive.Close()
img, err := decodeImage(p, cover)
err = archive.EntryFor(cover)
if err != nil {
return nil, err
}
size := archive.Size()
buf := make([]byte, size)
for size > 0 {
n, err := archive.Read(buf)
if err != nil && err != io.EOF {
break
}
size -= n
}
if size > 0 {
return nil, errors.New("Error Read")
}
img, err := decodeImage(bytes.NewReader(buf), cover)
if err != nil {
return nil, err
}
@@ -534,7 +536,7 @@ func getFiles() []string {
return files
}
// Returns sorted list of found image files for given directory
// Returns list of found image files for given directory
func getImages(path string) []string {
var images []string
@@ -759,7 +761,7 @@ func convertComic(file string, info os.FileInfo) {
// Parses command line flags
func parseFlags() {
opts = options{}
kingpin.Version("CBconvert 0.1.0")
kingpin.Version("CBconvert 0.2.0")
kingpin.CommandLine.Help = "Comic Book convert tool."
kingpin.Flag("png", "encode images to PNG instead of JPEG").Short('p').BoolVar(&opts.ToPNG)
kingpin.Flag("bmp", "encode images to 4-Bit BMP instead of JPEG").Short('b').BoolVar(&opts.ToBMP)
@@ -775,7 +777,7 @@ func parseFlags() {
kingpin.Flag("outdir", "output directory").Default(".").Short('o').StringVar(&opts.Outdir)
kingpin.Flag("size", "process only files larger then size (in MB)").Short('m').Default(strconv.Itoa(0)).Int64Var(&opts.Size)
kingpin.Flag("recursive", "process subdirectories recursively").Short('r').BoolVar(&opts.Recursive)
kingpin.Flag("quiet", "hide console output").Short('v').BoolVar(&opts.Quiet)
kingpin.Flag("quiet", "hide console output").Short('Q').BoolVar(&opts.Quiet)
kingpin.Arg("args", "filename or directory").Required().ExistingFilesOrDirsVar(&arguments)
kingpin.Parse()
}