All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.siegmann.epublib.bookprocessor.CoverpageBookProcessor Maven / Gradle / Ivy

The newest version!
package nl.siegmann.epublib.bookprocessor;

import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.Metadata;
import nl.siegmann.epublib.domain.Resource;
import nl.siegmann.epublib.domain.Resources;
import nl.siegmann.epublib.epub.BookProcessor;
import nl.siegmann.epublib.service.MediatypeService;
import nl.siegmann.epublib.util.CollectionUtil;
import nl.siegmann.epublib.util.ResourceUtil;
import org.apache.commons.io.FilenameUtils;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * If the book contains a cover image then this will add a cover page to the book.
 * If the book contains a cover html page it will set that page's first image as the book's cover image.
 * 
 * FIXME:
 *  will overwrite any "cover.jpg" or "cover.html" that are already there.
 *  
 * @author paul
 *
 */
public class CoverpageBookProcessor implements BookProcessor {

	public static int MAX_COVER_IMAGE_SIZE = 999;
	private static final Logger log = LoggerFactory.getLogger(CoverpageBookProcessor.class);
	public static final String DEFAULT_COVER_PAGE_ID = "cover";
	public static final String DEFAULT_COVER_PAGE_HREF = "cover.html";
	public static final String DEFAULT_COVER_IMAGE_ID = "cover-image";
	public static final String DEFAULT_COVER_IMAGE_HREF = "images/cover.png";
	
	@Override
	public Book processBook(Book book) {
		Metadata metadata = book.getMetadata();
		if(book.getCoverPage() == null && book.getCoverImage() == null) {
			return book;
		}
		Resource coverPage = book.getCoverPage();
		if (coverPage == null) {
			coverPage = findCoverPage(book);
			book.setCoverPage(coverPage);
		}
		Resource coverImage = book.getCoverImage();
		if(coverPage == null) {
			if(coverImage == null) {
				// give up
			} else { // coverImage != null
				if(StringUtils.isBlank(coverImage.getHref())) {
					coverImage.setHref(getCoverImageHref(coverImage, book));
				}
				String coverPageHtml = createCoverpageHtml(CollectionUtil.first(metadata.getTitles()), coverImage.getHref());
				coverPage = new Resource(null, coverPageHtml.getBytes(), getCoverPageHref(book), MediatypeService.XHTML);
				fixCoverResourceId(book, coverPage, DEFAULT_COVER_PAGE_ID);
			}
		} else { // coverPage != null
			if(book.getCoverImage() == null) {
				coverImage = getFirstImageSource(coverPage, book.getResources());
				book.setCoverImage(coverImage);
				if (coverImage != null) {
					book.getResources().remove(coverImage.getHref());
				}
			} else { // coverImage != null
				
			}
		}
		
		book.setCoverImage(coverImage);
		book.setCoverPage(coverPage);
		setCoverResourceIds(book);
		return book;
	}

//	private String getCoverImageHref(Resource coverImageResource) {
//		return "cover" + coverImageResource.getMediaType().getDefaultExtension();
//	}
	
	private Resource findCoverPage(Book book) {
		if (book.getCoverPage() != null) {
			return book.getCoverPage();
		}
		if (! (book.getSpine().isEmpty())) {
			return book.getSpine().getResource(0);
		}
		return null;
	}

	private void setCoverResourceIds(Book book) {
		if(book.getCoverImage() != null) {
			fixCoverResourceId(book, book.getCoverImage(), DEFAULT_COVER_IMAGE_ID);
		}
		if(book.getCoverPage() != null) {
			fixCoverResourceId(book, book.getCoverPage(), DEFAULT_COVER_PAGE_ID);
		}
	}

	
	private void fixCoverResourceId(Book book, Resource resource, String defaultId) {
		if (StringUtils.isBlank(resource.getId())) {
			resource.setId(defaultId);
		}
		book.getResources().fixResourceId(resource);
	}
	
	private String getCoverPageHref(Book book) {
		return DEFAULT_COVER_PAGE_HREF;
	}
	
	
	private String getCoverImageHref(Resource imageResource, Book book) {
		return DEFAULT_COVER_IMAGE_HREF;
	}
	
	private Resource getFirstImageSource(Resource titlePageResource, Resources resources) {
		try {
			Document titlePageDocument = ResourceUtil.getAsDocument(titlePageResource);
			NodeList imageElements = titlePageDocument.getElementsByTagName("img");
			for (int i = 0; i < imageElements.getLength(); i++) {
				String relativeImageHref = ((Element) imageElements.item(i)).getAttribute("src");
				String absoluteImageHref = calculateAbsoluteImageHref(relativeImageHref, titlePageResource.getHref());
				Resource imageResource = resources.getByHref(absoluteImageHref);
				if (imageResource != null) {
					return imageResource;
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}
	
	
	
	// package
	static String calculateAbsoluteImageHref(String relativeImageHref,
			String baseHref) {
		if (relativeImageHref.startsWith("/")) {
			return relativeImageHref;
		}
        String result = FilenameUtils.normalize(baseHref.substring(0, baseHref.lastIndexOf('/') + 1) + relativeImageHref, true);
        return result;
	}

	private String createCoverpageHtml(String title, String imageHref) {
	       return "" +
	       		"\n" +
	       		"\n" +
	       		"\t\n" +
	       		"\t\tCover\n" +
	       		"\t\t\n" +
	       		"\t\n" +
	       		"\t\n" +
	       		"\t\t
\n" + "\t\t\t\""\n" + "\t\t
\n" + "\t\n" + "\n"; } private Dimension calculateResizeSize(BufferedImage image) { Dimension result; if (image.getWidth() > image.getHeight()) { result = new Dimension(MAX_COVER_IMAGE_SIZE, (int) (((double) MAX_COVER_IMAGE_SIZE / (double) image.getWidth()) * (double) image.getHeight())); } else { result = new Dimension((int) (((double) MAX_COVER_IMAGE_SIZE / (double) image.getHeight()) * (double) image.getWidth()), MAX_COVER_IMAGE_SIZE); } return result; } @SuppressWarnings("unused") private byte[] createThumbnail(byte[] imageData) throws IOException { BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageData)); Dimension thumbDimension = calculateResizeSize(originalImage); BufferedImage thumbnailImage = createResizedCopy(originalImage, (int) thumbDimension.getWidth(), (int) thumbDimension.getHeight(), false); ByteArrayOutputStream result = new ByteArrayOutputStream(); ImageIO.write(thumbnailImage, "png", result); return result.toByteArray(); } private BufferedImage createResizedCopy(java.awt.Image originalImage, int scaledWidth, int scaledHeight, boolean preserveAlpha) { int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType); Graphics2D g = scaledBI.createGraphics(); if (preserveAlpha) { g.setComposite(AlphaComposite.Src); } g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null); g.dispose(); return scaledBI; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy