Commit e9c50522 authored by njean42's avatar njean42
Browse files

Ignore files that are not images.

Add support for license information (displayed on each page by the javascript reader).
parent 2533a062
......@@ -85,3 +85,20 @@ You can pass `kumiko` a `--debug-dir /path/to/debug-info` parameter that tells y
This will create an image for each page that Kumiko analysed, renamed `$filename-contours.jpg`.
These files will be found in the `/path/to/debug-info` folder (should exist and be writable).
Panel contours and image numbering is drawn onto every debugging image.
## License information
License information may be provided in a text file under the same directory as each image (named `myimage.jpg.license`).
It must be valid JSON data and will be available under a `license` key in the resulting JSON, for each image.
The fields known to our javascript reader are the following:
{
"title": "this image name",
"title_link": "a link to where this file can be found",
"author": "the author of this image",
"author_link": "a link to the author's web page",
"licence": "this image license",
"licence_link": "a link to the license"
}
......@@ -45,7 +45,7 @@ elif os.path.isfile(file_or_folder):
folder = os.path.dirname(file_or_folder)
else:
print("--input (-i) is not a file or directory: '"+file_or_folder+"'")
sys.exit()
sys.exit(1)
info = json.dumps(info)
......
#!/usr/bin/env python
import os
import os, json, sys
import cv2 as cv
import numpy as np
......@@ -23,9 +23,6 @@ class Kumiko:
if 'min_panel_size_ratio' in options and options['min_panel_size_ratio']:
self.options['min_panel_size_ratio'] = options['min_panel_size_ratio']
def read_image(self,filename):
return cv.imread(filename)
def parse_dir(self,directory):
filenames = []
......@@ -45,7 +42,11 @@ class Kumiko:
for filename in filenames:
if self.options['progress']:
print("\t",filename)
infos.append(self.parse_image(filename))
try:
infos.append(self.parse_image(filename))
except Exception:
pass # this file is not an image, will not be part of the results
return infos
......@@ -181,8 +182,9 @@ class Kumiko:
def parse_image(self,filename):
img = self.read_image(filename)
# TODO: handle error
img = cv.imread(filename)
if not isinstance(img,np.ndarray) or img.size == 0:
raise Exception('File {} is not an image'.format(filename))
size = list(img.shape[:2])
size.reverse() # get a [width,height] list
......@@ -193,6 +195,15 @@ class Kumiko:
'panels': []
}
# get license for this file
if os.path.isfile(filename+'.license'):
with open(filename+'.license') as fh:
try:
infos['license'] = json.load(fh)
except json.decoder.JSONDecodeError:
print('License file {} is not a valid JSON file'.format(filename+'.license'))
sys.exit(1)
self.gutterThreshold = Kumiko.getGutterThreshold(infos['size'])
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
......
from lib.panel import Panel
class HTML:
def header(title='',reldir=''):
......@@ -65,7 +63,8 @@ class HTML:
var reader = new Reader({{
container: $('#reader'),
comicsJson: {json},
images_dir: '{images_dir}'
images_dir: '{images_dir}',
controls: true
}});
reader.loadPage(0);
</script>
......
......@@ -50,7 +50,7 @@ class Panel:
def __setattr__(self,name,value):
if name in ['w','h']:
print("Fatal error, can't set a panel's width or height")
print("Fatal error, setting a panel's width or height is not allowed")
sys.exit(1)
super().__setattr__(name, value)
......
......@@ -40,7 +40,8 @@ class Reader {
});
this.gui.append(this.container);
this.add_controls();
if ('controls' in options && options['controls'])
this.add_controls();
window.addEventListener('orientationchange', function () {
setTimeout( function () { this.gotoPanel(this.currpanel); }.bind(this), 500); // slight delay to make it work better, not sure why :)
......@@ -87,6 +88,16 @@ class Reader {
this.container.children('img').remove();
this.container.prepend(img);
// show license
var license = this.get_license(imginfo);
if (license)
{
this.gui.append('<span class="license"/>');
this.gui.children('.license').html(license);
}
else
$('.license',this.gui).remove();
var was_zoomed = this.container.is('.zoomed');
this.drawPanels(imginfo);
......@@ -239,6 +250,27 @@ class Reader {
});
}
get_license(page)
{
if (!page.license)
return '';
var html = [];
for (var i=0; i < 3; i++)
{
var k = ['title','author','license'][i];
if (k in page.license)
{
var elt = page.license;
html.push(
{title:'',author:'by ',license:''}[k] +
(elt[k+'_link'] ? '<a target="_blank" href="'+elt[k+'_link']+'">'+elt[k]+'</a>' : elt[k])
);
}
}
return html.join(', ');
}
showMenu(show=true)
{
if (show)
......@@ -275,6 +307,12 @@ $(document).delegate( '.kumiko-reader', 'click touch', function (e) {
$(this).data('reader').next();
});
// Prevent click on page when clicking on license links
$(document).delegate( '.license a', 'click touch', function (e) {
e.stopPropagation();
});
// Show menu on double click
$(document).delegate( '.kumiko-reader', 'dblclick', function (e) {
$(this).data('reader').showMenu();
......
......@@ -49,6 +49,15 @@ ul {
right: 0;
}
.license {
position: absolute;
bottom: 0;
right: 15%;
}
.license a {
color: #ecf0f1;
}
/***** PANELS *****/
.panel {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment