1
0
mirror of https://github.com/ciromattia/kcc synced 2026-04-21 08:28:59 +00:00

Compare commits

...

8 Commits

Author SHA1 Message Date
Alex Xu
a7a9f35686 Update README.md 2026-04-19 10:27:52 -07:00
Alex Xu
d5146d02fc Update README.md 2026-04-19 10:10:18 -07:00
Alex Xu
b0374e127d Smarter covers (#1300)
* smart crop semi-wide covers

* make it even smarter

* make it even smarter

* adjust ratio
2026-04-18 07:39:23 -07:00
Alex Xu
894dbfc8a2 don't bisect images with < 1.16 or > 1.75 aspect ratios (#1301) 2026-04-17 18:03:31 -07:00
Alex Xu
72f98bb032 bump to 9.7.2 2026-04-16 13:30:08 -07:00
Alex Xu
96bf14d386 Kindle Scribe 2025 default is PDF (#1297) 2026-04-16 13:26:04 -07:00
Alex Xu
d4e1565e4a colorsoft is wrong too 2026-04-16 13:25:41 -07:00
Alex Xu
c3030e8bd1 Paperwhite 12th Gen is actually 1272x1696 2026-04-16 13:25:41 -07:00
4 changed files with 44 additions and 22 deletions

View File

@@ -11,7 +11,7 @@
like Kindle, Kobo, ReMarkable, and more.
Pages display in fullscreen without margins,
with proper fixed layout support.
Supported input formats include JPG/PNG image files in folders, archives, or PDFs.
Supported input formats include JPG/PNG image files in folders, archives like CBZ, or PDFs.
Supported output formats include MOBI/AZW3, EPUB, KEPUB, CBZ, and PDF.
KCC runs on Windows, macOS, and Linux.
@@ -115,15 +115,14 @@ For flatpak, Docker, and AppImage versions, refer to the wiki: https://github.co
## FAQ
- Should I use Calibre?
- No. Calibre doesn't properly support fixed layout EPUB/MOBI, so modifying KCC output (even just metadata!) in Calibre can break the formatting.
Additionally, it will break page numbers.
Viewing KCC output in Calibre will also not work properly.
On 7th gen and later Kindles running firmware 5.15.1+, you can get cover thumbnails simply by USB dropping into documents folder.
On 6th gen and older, you can get cover thumbnails by keeping Kindle plugged in during conversion.
If you are careful to not modify the file however, you can still use Calibre, but direct USB dropping is reccomended.
Direct USB dropping is reccomended.
- Blank pages?
- May happen when [using PNG with Kindle Scribe](https://github.com/ciromattia/kcc/issues/665) or [any format with a Kindle Colorsoft](https://github.com/ciromattia/kcc/issues/768). Solve by using JPG with Kindle Scribe or buying a Kobo Colour. Happens more often when turning pages really fast.
- May happen when [using PNG with Kindle Scribe](https://github.com/ciromattia/kcc/issues/665) or [any format with a Kindle Colorsoft](https://github.com/ciromattia/kcc/issues/768). Solve by using JPG with Kindle Scribe or buying a Kobo Colour. Happens more often when turning pages really fast. You can try PDF output.
Going back a few pages and exiting and re-entering book should fix it temporarily.
- What output format should I use?
- MOBI for Kindles. CBZ for Kindle DX. CBZ for Koreader. KEPUB for Kobo. PDF for ReMarkable.
- MOBI for Kindles. CBZ for Kindle DX. CBZ for Koreader. KEPUB for Kobo. PDF for ReMarkable or Kindle Scribe 2025.
- All options have additional information in tooltips if you hover over the option.
- To get the converted book onto your Kindle/Kobo, just drag and drop the mobi/kepub into the documents folder on your Kindle/Kobo via USB
- Kindle panel view not working?
@@ -137,9 +136,6 @@ For flatpak, Docker, and AppImage versions, refer to the wiki: https://github.co
(no login required). Works much better than previously recommended Android File Transfer. Cannot run simutaneously with other transfer apps.
- How to make AZW3 instead of MOBI?
- The `.mobi` file generated by KCC is a dual filetype, it's both MOBI and AZW3. The file extension is `.mobi` for compatibility reasons.
- [Windows 7 support](https://github.com/ciromattia/kcc/issues/678)
- Image too dark?
- The default gamma correction of 1.8 makes the image darker, and is useful for faded/gray artwork/text. Disable by setting gamma = 1.0
- Huge margins / slow page turns?
- You likely modified the file during transfer using a 3rd party app. Try simply dragging and dropping the final mobi/kepub file into the Kindle documents folder via USB.
@@ -198,8 +194,9 @@ sudo apt-get install python3 p7zip-full python3-pil python3-psutil python3-slugi
'KV': ("Kindle Voyage", (1072, 1448), Palette16, 1.0),
'KPW34': ("Kindle Paperwhite 3/4", (1072, 1448), Palette16, 1.0),
'KPW5': ("Kindle Paperwhite 5/Signature Edition", (1236, 1648), Palette16, 1.0),
'KO': ("Kindle Oasis 2/3/Paperwhite 12", (1264, 1680), Palette16, 1.0),
'KCS': ("Kindle Colorsoft", (1264, 1680), Palette16, 1.0),
'KPW6': ("Kindle Paperwhite 6", (1272, 1696), Palette16, 1.0),
'KO': ("Kindle Oasis 2/3", (1264, 1680), Palette16, 1.0),
'KCS': ("Kindle Colorsoft", (1272, 1696), Palette16, 1.0),
'KS1860': ("Kindle 1860", (1860, 1920), Palette16, 1.0),
'KS1920': ("Kindle 1920", (1920, 1920), Palette16, 1.0),
'KS': ("Kindle Scribe 1/2", (1860, 2480), Palette16, 1.0),

View File

@@ -1260,10 +1260,10 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS',
},
"Kindle Scribe 3": {
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS3',
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 3, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS3',
},
"Kindle Scribe Colorsoft": {
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': True, 'Label': 'KSCS',
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 3, 'DefaultUpscale': False, 'ForceColor': True, 'Label': 'KSCS',
},
"Kindle 11": {
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'K11',
@@ -1272,7 +1272,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KPW5',
},
"Kindle Paperwhite 12": {
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KO',
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KPW6',
},
"Kindle Colorsoft": {
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': True, 'Label': 'KCS',

View File

@@ -1,4 +1,4 @@
__version__ = '9.7.1'
__version__ = '9.7.2'
__license__ = 'ISC'
__copyright__ = '2012-2022, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>, darodi'
__docformat__ = 'restructuredtext en'

View File

@@ -98,14 +98,15 @@ class ProfileData:
'KV': ("Kindle Voyage", (1072, 1448), Palette16, 1.0),
'KPW34': ("Kindle Paperwhite 3/4/Oasis", (1072, 1448), Palette16, 1.0),
'K810': ("Kindle 8/10", (600, 800), Palette16, 1.0),
'KO': ("Kindle Oasis 2/3/Paperwhite 12", (1264, 1680), Palette16, 1.0),
'KO': ("Kindle Oasis 2/3", (1264, 1680), Palette16, 1.0),
'K11': ("Kindle 11", (1072, 1448), Palette16, 1.0),
'KPW5': ("Kindle Paperwhite 5/Signature Edition", (1236, 1648), Palette16, 1.0),
'KPW6': ("Kindle Paperwhite 6", (1272, 1696), Palette16, 1.0),
'KS1860': ("Kindle 1860", (1860, 1920), Palette16, 1.0),
'KS1920': ("Kindle 1920", (1920, 1920), Palette16, 1.0),
'KS1240': ("Kindle 1240", (1240, 1860), Palette16, 1.0),
'KS': ("Kindle Scribe 1/2", (1860, 2480), Palette16, 1.0),
'KCS': ("Kindle Colorsoft", (1264, 1680), Palette16, 1.0),
'KCS': ("Kindle Colorsoft", (1272, 1696), Palette16, 1.0),
'KS3': ("Kindle Scribe 3", (1986, 2648), Palette16, 1.0),
'KSCS': ("Kindle Scribe Colorsoft", (1986, 2648), Palette16, 1.0),
}
@@ -193,8 +194,10 @@ class ComicPageParser:
new_image.paste(pageone, (0, 0))
new_image.paste(pagetwo, (0, height))
self.payload.append(['N', self.source, new_image, self.fill])
elif (width > height) != (dstwidth > dstheight) and width <= dstheight and height <= dstwidth \
and not self.opt.webtoon and self.opt.splitter == 1:
elif self.opt.webtoon:
self.payload.append(['N', self.source, self.image, self.fill])
# rotate only TODO dead code?
elif (width > height) != (dstwidth > dstheight) and width <= dstheight and height <= dstwidth and self.opt.splitter == 1:
spread = self.image
if not self.opt.norotate:
if not self.opt.rotateright:
@@ -202,8 +205,10 @@ class ComicPageParser:
else:
spread = spread.rotate(-90, Image.Resampling.BICUBIC, True)
self.payload.append(['R', self.source, spread, self.fill])
elif (width > height) != (dstwidth > dstheight) and not self.opt.webtoon:
if self.opt.splitter != 1 and width / height < 2:
# elif wide enough to split
elif (width > height) != (dstwidth > dstheight) and width / height > 1.16:
# if (split) or (split and rotate)
if self.opt.splitter != 1 and width / height < 1.75:
if width > height:
leftbox = (0, 0, int(width / 2), height)
rightbox = (int(width / 2), 0, width, height)
@@ -218,7 +223,9 @@ class ComicPageParser:
pagetwo = self.image.crop(rightbox)
self.payload.append(['S1', self.source, pageone, self.fill])
self.payload.append(['S2', self.source, pagetwo, self.fill])
if self.opt.splitter > 0 or (self.opt.splitter == 0 and width / height >= 2):
# if (rotate) or (split and rotate)
if self.opt.splitter > 0 or (self.opt.splitter == 0 and width / height >= 1.75):
spread = self.image
if not self.opt.norotate:
if not self.opt.rotateright:
@@ -601,12 +608,30 @@ class Cover:
self.image = self.image.crop((w/6, 0, w/2 - w * 0.02, h))
else:
self.image = self.image.crop((w/2 + w * 0.02, 0, 5/6 * w, h))
elif w / h > 1.83:
self.smartcover = True
if self.options.righttoleft:
self.image = self.image.crop((w * .19, 0, w * .575, h))
else:
self.image = self.image.crop((w * .425, 0, .81 * w, h))
elif w / h > 1.7:
self.smartcover = True
if self.options.righttoleft:
self.image = self.image.crop((w * .2, 0, w * .583, h))
else:
self.image = self.image.crop((w * .417, 0, .8 * w, h))
elif w / h > 1.34:
self.smartcover = True
if self.options.righttoleft:
self.image = self.image.crop((0, 0, w/2 - w * 0.03, h))
else:
self.image = self.image.crop((w/2 + w * 0.03, 0, w, h))
elif w / h > 1.0:
self.smartcover = True
if self.options.righttoleft:
self.image = self.image.crop((w * .36, 0, w, h))
else:
self.image = self.image.crop((w, 0, .64 * w, h))
def save_to_folder(self, target, tomeid, len_tomes=0):
try: