voodoojello
8/8/2011 - 11:12 PM

Create ebook (EPUB) from PNG, JPG, or GIF images

Create ebook (EPUB) from PNG, JPG, or GIF images

#!/usr/bin/perl -w
#
my $app = {
	'name'     => 'img2epub',
	'desc'     => 'Create ebook (EPUB) from PNG, JPG, or GIF images',
	'modified' => 'Mon Aug 15 06:03:05 CDT 2011',
	'author'   => 'mark page [m.e.page@gmail.com]',
	'version'  => '0.0.1.4b',
	};

my ($manifest,$spine,$uuid,$firstpage,$coverimg);

print '=' x 80 . "\n";
print ' ' . $app->{'name'} . ' v' . $app->{'version'} . ' - ' . $app->{'desc'} . "\n";
print ' ' . $app->{'modified'} . ' - ' . $app->{'author'} . "\n";
print '=' x 80 . "\n\n";

print '   Path: '; chomp(my $path   = <STDIN>);
print '  Title: '; chomp(my $title  = <STDIN>);
print ' Author: '; chomp(my $author = <STDIN>);

unless ($title & $path & $author) { die 'Not enough input!'; }
unless (stat("$path")) { die 'Invalid image path!'; }

print "\n";
print ' >> Creating EPUB Directory structure.' . "\n";
`mkdir ./"$title"`;
`mkdir ./"$title"/META-INF`;
`mkdir ./"$title"/OEBPS`;
`mkdir ./"$title"/OEBPS/Text`;
`mkdir ./"$title"/OEBPS/Images`;

print ' >> Generating local (psudeo) UUID.' . "\n";
my $uuid_raw = '00000000-0000-0000-0000-000000000000';
for my $i (0 .. length($uuid_raw)) {
	if (substr($uuid_raw,$i,1) ne '-') {
		$uuid .= int(rand(9));
		}
	else {
		$uuid .= substr($uuid_raw,$i,1);
		}
	}

print ' >> Copying Images and Writing OEBPS data...' . "\n";
chomp(my @imgs = `ls "$path"/*.png *.jpg *.gif 2>/dev/null`); #*/
for $i (0 .. (scalar(@imgs) - 1)) {
	my $imgname  = (split('/',$imgs[$i]))[-1];
	my $imgtype  = substr($imgname,-3,3);
	my $alttype  = (split('_',$imgname))[0];
	my $number   = (split('_',$imgname))[-1];
	
	$number =~ s/\.png//; $number =~ s/\.jpg//; $number =~ s/\.gif//;
	
	if ($number =~ m/0000/i or $number =~ m/cover/i) {
		$alttype   = 'cover';
		$firstpage = 'content' . $number . '.xhtml';
		$coverimg  = $imgname;
		}
	else {
		$alttype = $alttype . $number;
		}

	`cp "$imgs[$i]" ./"$title"/OEBPS/Images/$imgname`;

	$manifest .= "\t\t" . '<item href="Images/' . $imgname . '" id="' . $imgname . '" media-type="image/' . $imgtype . '" />' . "\n";
	$manifest .= "\t\t" . '<item href="Text/content' . $number . '.xhtml" id="content' . $number . '.xhtml" media-type="application/xhtml+xml" />' . "\n";
	$spine    .= "\t\t" . '<itemref idref="content' . $number . '.xhtml" />' . "\n";

	open (XML,'>',"./$title/OEBPS/Text/content$number.xhtml");
	print XML '<?xml version="1.0" encoding="utf-8" standalone="no"?>' . "\n";
	print XML '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"' . "\n";
	print XML '  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">' . "\n\n";
	print XML '<html xmlns="http://www.w3.org/1999/xhtml">' . "\n";
	print XML '<head>' . "\n";
	print XML '	<title></title>' . "\n";
	print XML '</head>' . "\n\n";                                           
	print XML '<body>' . "\n";
	print XML '	<div><img alt="' . $alttype . '" src="../Images/' . $imgname . '" /></div>' . "\n";
	print XML '</body>' . "\n";
	print XML '</html>' . "\n";
	close(XML);
	}


# mimetype
print ' >> Writing MIMETYPE data identifier' . "\n";                                   
open(MIME,'>',"./$title/mimetype"); 
print MIME 'application/epub+zip';
close(MIME);


# container.xml
print ' >> Writing META-INF (container) data.' . "\n";
open(META,'>',"./$title/META-INF/container.xml");
print META '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
print META '<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">' . "\n";
print META '    <rootfiles>' . "\n";
print META '        <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>' . "\n";
print META '    </rootfiles>' . "\n";
print META '</container>' . "\n";
close(META);


# toc.ncx
print ' >> Writing TOC/NCX data.' . "\n";
open(TOC,'>',"./$title/OEBPS/toc.ncx");
print TOC '<?xml version="1.0" encoding="utf-8"?>' . "\n";
print TOC '<!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN"' . "\n";
print TOC '  "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">' . "\n\n";
print TOC '<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">' . "\n";
print TOC '<head>' . "\n";
print TOC '	<meta name="dtb:uid" content="urn:uuid:' . $uuid . '" />' . "\n";
print TOC '	<meta name="dtb:depth" content="0" />' . "\n";
print TOC '	<meta name="dtb:totalPageCount" content="0" />' . "\n";
print TOC '	<meta name="dtb:maxPageNumber" content="0" />' . "\n";
print TOC '</head>' . "\n";
print TOC '<docTitle>' . "\n";
print TOC '	<text></text>' . "\n";
print TOC '</docTitle>' . "\n";
print TOC '<navMap>' . "\n";
print TOC '	<navPoint id="navPoint-1" playOrder="1">' . "\n";
print TOC '		<navLabel>' . "\n";
print TOC '			<text>' . $title . '</text>' . "\n";
print TOC '		</navLabel>' . "\n";
print TOC '		<content src="Text/' . $firstpage . '" />' . "\n";
print TOC '	</navPoint>' . "\n";
print TOC '</navMap>' . "\n";
print TOC '</ncx>' . "\n";
close(TOC);


# content.opf
print ' >> Writing OPF content data.' . "\n";
open(OPF,'>',"./$title/OEBPS/content.opf");
print OPF '<?xml version="1.0" encoding="utf-8" standalone="yes"?>' . "\n";
print OPF '<package xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId" version="2.0">' . "\n";
print OPF '	<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">' . "\n";
print OPF '		<dc:identifier id="BookId" opf:scheme="UUID">urn:uuid:' . $uuid . '</dc:identifier>' . "\n";
print OPF '		<dc:title>' . $title . '</dc:title>' . "\n";
print OPF '		<dc:creator opf:role="aut">' . $author . '</dc:creator>' . "\n";
print OPF '		<dc:language>en</dc:language>' . "\n";
print OPF '		<meta content="' . $coverimg . '" name="cover" />' . "\n";
print OPF '	</metadata>' . "\n";
print OPF '	<manifest>' . "\n";
print OPF '		<item href="toc.ncx" id="ncx" media-type="application/x-dtbncx+xml" />' . "\n";
print OPF $manifest . "\n";
print OPF '	</manifest>' . "\n";
print OPF '	<spine toc="ncx">' . "\n";
print OPF $spine . "\n";
print OPF '	</spine>' . "\n";
print OPF '	<guide>' . "\n";
print OPF '		<reference href="Text/' . $firstpage . '" title="Cover" type="cover" />' . "\n";
print OPF '	</guide>' . "\n";
print OPF '</package>' . "\n";
close(OPF);

print ' >> Compressing EPUB...' . "\n";
`cd ./"$title"/ \&\& zip -r -0 "../$title\.epub" *`;

print ' >> Done.' . "\n\n";

exit;

__END__