Merge branch 'master' into options
12
INSTALL.md
@ -4,11 +4,11 @@ For local development / building stand-alone binaries.
|
|||||||
|
|
||||||
You need [Python 2.7](https://www.python.org/downloads/release/python-2718/).
|
You need [Python 2.7](https://www.python.org/downloads/release/python-2718/).
|
||||||
|
|
||||||
If you are using Windows download the
|
If you are using Windows
|
||||||
`Windows x86 MSI installer`
|
and want to build a stand-alone binary
|
||||||
because 32 bit Python is needed to create
|
download the `Windows x86 MSI installer`
|
||||||
a Windows executable with `py2exe`.
|
because `py2exe` for Python 2 doesn't work with 64 bit.
|
||||||
The performance increase from 64 bit is negligible.
|
Any performance increase from 64 bit is negligible.
|
||||||
|
|
||||||
Be sure to add `python` to `PATH` during installation.
|
Be sure to add `python` to `PATH` during installation.
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ To actually build a stand-alone `.exe`, install
|
|||||||
A standalone binary can be created in the `dist` folder via
|
A standalone binary can be created in the `dist` folder via
|
||||||
|
|
||||||
```
|
```
|
||||||
(venv) > python setup.py install
|
(venv) > python setup.py
|
||||||
```
|
```
|
||||||
|
|
||||||
You may get an error which can be solved by looking at
|
You may get an error which can be solved by looking at
|
||||||
|
44
README.md
@ -1,4 +1,13 @@
|
|||||||
# Mangle #
|
<!-- +++
|
||||||
|
Area = "projects"
|
||||||
|
GitHub = "mangle"
|
||||||
|
Layout = "page"
|
||||||
|
Tags = ["kindle", "manga", "mangle", "pil", "pyqt", "python", "gpl license"]
|
||||||
|
Description = "Manga processor for the Kindle e-book reader."
|
||||||
|
Collection = "ProjectsComplete"
|
||||||
|
+++ -->
|
||||||
|
|
||||||
|
# Mangle
|
||||||
|
|
||||||
Mangle is a cross-platform image converter and optimizer built for reading Manga on the Amazon Kindle and other E-ink
|
Mangle is a cross-platform image converter and optimizer built for reading Manga on the Amazon Kindle and other E-ink
|
||||||
devices written in Python. With this application you can easily:
|
devices written in Python. With this application you can easily:
|
||||||
@ -8,19 +17,12 @@ devices written in Python. With this application you can easily:
|
|||||||
* Downsample and rotate images for optimal viewing on Kindle, convert to grayscale to save space and improve contrast.
|
* Downsample and rotate images for optimal viewing on Kindle, convert to grayscale to save space and improve contrast.
|
||||||
* Automatically generate book meta-data so that your Manga is always properly detected and viewable in-order.
|
* Automatically generate book meta-data so that your Manga is always properly detected and viewable in-order.
|
||||||
|
|
||||||
### Screenshots ###
|
[![](img/kindle1-thumb.png)](img/kindle1.png)
|
||||||
|
[![](img/kindle2-thumb.png)](img/kindle2.png)
|
||||||
|
[![](img/kindle3-thumb.png)](img/kindle3.png)
|
||||||
|
[![](img/kindle4-thumb.png)](img/kindle4.png)
|
||||||
|
|
||||||
[![Main window](https://foosoft.net/projects/mangle/img/main-thumb.png)](https://foosoft.net/projects/mangle/img/main.png)
|
## Motivation
|
||||||
[![Options dialog](https://foosoft.net/projects/mangle/img/options-thumb.png)](https://foosoft.net/projects/mangle/img/options.png)
|
|
||||||
|
|
||||||
### On the Kindle... ###
|
|
||||||
|
|
||||||
[![](https://foosoft.net/projects/mangle/img/kindle1-thumb.png)](https://foosoft.net/projects/mangle/img/kindle1.png)
|
|
||||||
[![](https://foosoft.net/projects/mangle/img/kindle2-thumb.png)](https://foosoft.net/projects/mangle/img/kindle2.png)
|
|
||||||
[![](https://foosoft.net/projects/mangle/img/kindle3-thumb.png)](https://foosoft.net/projects/mangle/img/kindle3.png)
|
|
||||||
[![](https://foosoft.net/projects/mangle/img/kindle4-thumb.png)](https://foosoft.net/projects/mangle/img/kindle4.png)
|
|
||||||
|
|
||||||
## Motivation ##
|
|
||||||
|
|
||||||
Many years ago I received an Amazon Kindle as a gift. I immediately began playing around with it and reading about
|
Many years ago I received an Amazon Kindle as a gift. I immediately began playing around with it and reading about
|
||||||
certain undocumented features that the Kindle has to offer. After a couple of hours I discovered it to be the perfect
|
certain undocumented features that the Kindle has to offer. After a couple of hours I discovered it to be the perfect
|
||||||
@ -54,7 +56,7 @@ However... The Kindle's image viewer does have certain shortcomings:
|
|||||||
Mangle was born out of my annoyance with these issues. The program name is a portmanteau of "Manga" and "Kindle"; I
|
Mangle was born out of my annoyance with these issues. The program name is a portmanteau of "Manga" and "Kindle"; I
|
||||||
thought it was pretty clever at the time.
|
thought it was pretty clever at the time.
|
||||||
|
|
||||||
## Usage ##
|
## Usage
|
||||||
|
|
||||||
1. Add the desired images and image directories to the current book.
|
1. Add the desired images and image directories to the current book.
|
||||||
2. Re-order the images as needed (files pre-sorted alphabetically).
|
2. Re-order the images as needed (files pre-sorted alphabetically).
|
||||||
@ -63,20 +65,14 @@ thought it was pretty clever at the time.
|
|||||||
5. Export your images, selecting the `pictures` directory you just created.
|
5. Export your images, selecting the `pictures` directory you just created.
|
||||||
6. Enjoy your Manga (if it doesn't show up, press <kbd>Alt</kbd> + <kbd>Z</kbd> while on the home menu).
|
6. Enjoy your Manga (if it doesn't show up, press <kbd>Alt</kbd> + <kbd>Z</kbd> while on the home menu).
|
||||||
|
|
||||||
## Dependencies ##
|
## Dependencies
|
||||||
|
|
||||||
* [PyQt4](https://riverbankcomputing.com/software/pyqt/download)
|
* [PyQt4](https://riverbankcomputing.com/software/pyqt/download)
|
||||||
* [Python 2.7](http://www.python.org/download/releases/2.7/)
|
* [Python 2.7](http://www.python.org/download/releases/2.7/)
|
||||||
* [Pillow (PIL)](https://pypi.org/project/Pillow/)
|
* [Pillow (PIL)](https://pypi.org/project/Pillow/)
|
||||||
* [ReportLab](https://pypi.org/project/reportlab/)
|
* [ReportLab](https://pypi.org/project/reportlab/)
|
||||||
|
|
||||||
## Installation ##
|
## Installation
|
||||||
|
|
||||||
Pre-build binaries are available for the platforms listed below. I don't have the means to make MacOS X releases myself,
|
Pre-built binaries are available for download from the project's [releases
|
||||||
so I am providing the old (and unsupported) package built by Rob White instead. Linux users should run Mangle directly
|
page](https://github.com/FooSoft/mangle/releases).
|
||||||
from source.
|
|
||||||
|
|
||||||
* [mangle\_win.zip](https://foosoft.net/projects/mangle/dl/mangle_win.zip)
|
|
||||||
* [mangle\_osx.zip](https://foosoft.net/projects/mangle/dl/mangle_osx.zip) (quite old)
|
|
||||||
|
|
||||||
Check [INSTALL.md](INSTALL.md) for build instructions.
|
|
||||||
|
BIN
img/kindle1-thumb.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
img/kindle1.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
img/kindle2-thumb.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
img/kindle2.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
img/kindle3-thumb.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
img/kindle3.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
img/kindle4-thumb.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
img/kindle4.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
80
mangle-cli.py
Executable file
@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env python2
|
||||||
|
"""python mangle-cli.py extracted_cbz_folder/*
|
||||||
|
-d directory_name defaults to ./
|
||||||
|
-t title defaults 'Unknown'
|
||||||
|
-o book.outputFormat defaults to 'CBZ only'
|
||||||
|
|
||||||
|
NOTE order of arguments for image files is significant.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
mkdir my_comic
|
||||||
|
cd my_comic
|
||||||
|
7z x /full/path/my/comic.cbz
|
||||||
|
cd ..
|
||||||
|
python mangle-cli.py -tmy_comic my_comic/*
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import getopt
|
||||||
|
|
||||||
|
import mangle.cbz
|
||||||
|
import mangle.image
|
||||||
|
from mangle.image import ImageFlags
|
||||||
|
|
||||||
|
|
||||||
|
class FakeBook:
|
||||||
|
device = 'Kindle 2/3/Touch' # See mangle/image.py KindleData.Profiles
|
||||||
|
outputFormat = 'CBZ only'
|
||||||
|
title = 'Unknown'
|
||||||
|
imageFlags = ImageFlags.Orient | ImageFlags.Resize | ImageFlags.Quantize
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(sys.argv[1:], 'd:t:o:')
|
||||||
|
except getopt.GetoptError, err:
|
||||||
|
print(str(err))
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
directory = '.'
|
||||||
|
|
||||||
|
book = FakeBook()
|
||||||
|
book.device = 'Kindle 2/3/Touch'
|
||||||
|
#book.device = 'Kindle Paperwhite 1 & 2'
|
||||||
|
book.outputFormat = 'CBZ only'
|
||||||
|
book.title = 'Unknown'
|
||||||
|
|
||||||
|
|
||||||
|
for o,a in opts:
|
||||||
|
if o == '-d':
|
||||||
|
directory = a
|
||||||
|
elif o == '-t':
|
||||||
|
book.title = a
|
||||||
|
elif o == '-o':
|
||||||
|
book.outputFormat = a
|
||||||
|
|
||||||
|
|
||||||
|
bookPath = os.path.join(directory, book.title)
|
||||||
|
|
||||||
|
archive = mangle.cbz.Archive(bookPath)
|
||||||
|
|
||||||
|
if not os.path.isdir(bookPath):
|
||||||
|
os.makedirs(bookPath)
|
||||||
|
|
||||||
|
|
||||||
|
for index in range(0, len(args)):
|
||||||
|
target = os.path.join(bookPath, '%05d.png' % index) # FIXME preserve original; format and name?
|
||||||
|
|
||||||
|
print(index, args[index], target) # cheap display progress
|
||||||
|
mangle.image.convertImage(args[index], target, str(book.device), book.imageFlags)
|
||||||
|
archive.addFile(target);
|
||||||
|
|
||||||
|
|
||||||
|
if 'Image' not in book.outputFormat:
|
||||||
|
shutil.rmtree(bookPath)
|
||||||
|
|
||||||
|
archive.close()
|
||||||
|
|
@ -157,6 +157,16 @@ def fitImage(image, size, method=Image.ANTIALIAS):
|
|||||||
|
|
||||||
@protect_bad_image
|
@protect_bad_image
|
||||||
def fillImage(image, size):
|
def fillImage(image, size):
|
||||||
|
widthDev, heightDev = size
|
||||||
|
widthImg, heightImg = image.size
|
||||||
|
|
||||||
|
imgRatio = float(widthImg) / float(heightImg)
|
||||||
|
devRatio = float(widthDev) / float(heightDev)
|
||||||
|
|
||||||
|
# don't crop 2 page spreads.
|
||||||
|
if imgRatio > devRatio:
|
||||||
|
return resizeImage(image, size)
|
||||||
|
|
||||||
return ImageOps.fit(image, size, Image.ANTIALIAS)
|
return ImageOps.fit(image, size, Image.ANTIALIAS)
|
||||||
|
|
||||||
|
|
||||||
@ -202,6 +212,9 @@ def orientImage(image, size):
|
|||||||
widthDev, heightDev = size
|
widthDev, heightDev = size
|
||||||
widthImg, heightImg = image.size
|
widthImg, heightImg = image.size
|
||||||
|
|
||||||
|
if widthImg <= widthDev and heightImg <= heightDev:
|
||||||
|
return image
|
||||||
|
|
||||||
if (widthImg > heightImg) != (widthDev > heightDev):
|
if (widthImg > heightImg) != (widthDev > heightDev):
|
||||||
return image.rotate(90, Image.BICUBIC, True)
|
return image.rotate(90, Image.BICUBIC, True)
|
||||||
return image
|
return image
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
Pillow==6.2.2
|
|
||||||
py2exe-py2==0.6.9; platform_system=='Windows'
|
py2exe-py2==0.6.9; platform_system=='Windows'
|
||||||
PyQt4 @ https://download.lfd.uci.edu/pythonlibs/w4tscw6k/cp27/PyQt4-4.11.4-cp27-cp27m-win32.whl; platform_system=='Windows'
|
PyQt4 @ https://download.lfd.uci.edu/pythonlibs/w4tscw6k/cp27/PyQt4-4.11.4-cp27-cp27m-win32.whl; platform_system=='Windows'
|
||||||
reportlab==3.5.59
|
reportlab==3.5.59
|
||||||
|