2 * Meviz - Various tools collection to work with multimedia. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
7 package eu.svjatoslav.meviz.htmlindexer;
9 import eu.svjatoslav.meviz.htmlindexer.layouts.Layout;
10 import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout;
11 import org.w3c.dom.NamedNodeMap;
12 import org.w3c.dom.Node;
13 import org.w3c.dom.NodeList;
15 import javax.imageio.ImageReader;
16 import javax.imageio.metadata.IIOMetadata;
17 import javax.imageio.metadata.IIOMetadataNode;
19 import java.awt.image.BufferedImage;
20 import java.io.BufferedReader;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.HashSet;
26 import java.util.zip.CRC32;
28 import static org.openimaj.image.ImageUtilities.createBufferedImage;
29 import static org.openimaj.image.ImageUtilities.readMBF;
32 private static File lastLoadedFile;
33 private static BufferedImage lastLoadedBufferedImage;
36 * Load image into {@link BufferedImage} and return it. Caches last loaded
37 * image to speed up subsequent loading attempts.
39 * @throws ImageFormatError
42 public static BufferedImage getBufferedImage(final File file)
43 throws ImageFormatError, IOException {
44 if (file.equals(lastLoadedFile))
45 return lastLoadedBufferedImage;
47 lastLoadedBufferedImage = createBufferedImage(readMBF(file));
48 lastLoadedFile = file;
50 if (lastLoadedBufferedImage == null) {
51 System.out.println("Error reading image: " + file);
52 throw new ImageFormatError("File: " + file
53 + " is not a valid image.");
57 return lastLoadedBufferedImage;
60 public static File getLayoutIndexFile(final Layout layout,
61 final File directoryToIndex) {
63 final String indexFilePath = directoryToIndex.getAbsolutePath()
64 + "/index" + layout.getFileNameSuffix() + ".html";
66 return new File(indexFilePath);
69 public static HashSet<Layout> getLayouts() {
70 final HashSet<Layout> layouts = new HashSet<>();
71 layouts.add(new MixedLayout());
75 public static String getStringCrcAsHex(final String input) {
77 // create a new CRC-calculating object
78 final CRC32 crc = new CRC32();
80 // loop, calculating CRC for each byte of the string
81 // There is no CRC16.update(byte[]) method.
82 for (final byte b : input.getBytes())
85 // note use crc.value, not crc.getValue()
87 return Integer.toHexString((int) crc.getValue())
91 public static File getThumbnailsDirectory(final File directoryToIndex) {
92 return new File(getThumbnailsDirectoryPath(directoryToIndex));
95 public static String getThumbnailsDirectoryPath(final File directoryToIndex) {
96 return directoryToIndex.getAbsolutePath() + "/"
97 + Constants.THUMBNAILS_DIRECTORY_NAME + "/";
100 public static boolean isMevizGeneratedIndexFile(final File indexFile)
103 boolean isMevizFile = false;
105 final FileReader fileReader = new FileReader(indexFile);
106 final BufferedReader reader = new BufferedReader(fileReader);
111 final String line = reader.readLine();
116 if (line.contains(Constants.HTML_MAGIC_STRING)) {
129 * TODO: URL path component is encoded differently from URL query parameter.
130 * Also some URL encoding might work for HTML on local filesystem, while other
131 * stuff works for web. Things must be cleared up here. Currently they are mixed and
134 public static String urlEncode(String string) {
135 if (string.startsWith("./"))
136 string = string.substring(2);
138 // TODO: get rid of UrlParamEncoder.
139 return UrlParamEncoder.encode(string);
142 // return URLEncoder.encode(string, UTF_8).replace("+", "%20");
143 // } catch (UnsupportedEncodingException e) {
144 // throw new RuntimeException(e);
148 public static ImageFrame[] readGIF(ImageReader reader) throws IOException {
149 ArrayList<ImageFrame> frames = new ArrayList<ImageFrame>(2);
154 IIOMetadata metadata = reader.getStreamMetadata();
155 if (metadata != null) {
156 IIOMetadataNode globalRoot = (IIOMetadataNode) metadata.getAsTree(metadata.getNativeMetadataFormatName());
158 NodeList globalScreenDescriptor = globalRoot.getElementsByTagName("LogicalScreenDescriptor");
160 if (globalScreenDescriptor != null && globalScreenDescriptor.getLength() > 0) {
161 IIOMetadataNode screenDescriptor = (IIOMetadataNode) globalScreenDescriptor.item(0);
163 if (screenDescriptor != null) {
164 width = Integer.parseInt(screenDescriptor.getAttribute("logicalScreenWidth"));
165 height = Integer.parseInt(screenDescriptor.getAttribute("logicalScreenHeight"));
170 BufferedImage master = null;
171 Graphics2D masterGraphics = null;
173 for (int frameIndex = 0;; frameIndex++) {
176 image = reader.read(frameIndex);
177 } catch (IndexOutOfBoundsException io) {
181 if (width == -1 || height == -1) {
182 width = image.getWidth();
183 height = image.getHeight();
186 IIOMetadataNode root = (IIOMetadataNode) reader.getImageMetadata(frameIndex).getAsTree("javax_imageio_gif_image_1.0");
187 IIOMetadataNode gce = (IIOMetadataNode) root.getElementsByTagName("GraphicControlExtension").item(0);
188 int delay = Integer.valueOf(gce.getAttribute("delayTime"));
189 String disposal = gce.getAttribute("disposalMethod");
194 if (master == null) {
195 master = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
196 masterGraphics = master.createGraphics();
197 masterGraphics.setBackground(new Color(0, 0, 0, 0));
199 NodeList children = root.getChildNodes();
200 for (int nodeIndex = 0; nodeIndex < children.getLength(); nodeIndex++) {
201 Node nodeItem = children.item(nodeIndex);
202 if (nodeItem.getNodeName().equals("ImageDescriptor")) {
203 NamedNodeMap map = nodeItem.getAttributes();
204 x = Integer.valueOf(map.getNamedItem("imageLeftPosition").getNodeValue());
205 y = Integer.valueOf(map.getNamedItem("imageTopPosition").getNodeValue());
209 masterGraphics.drawImage(image, x, y, null);
211 BufferedImage copy = new BufferedImage(master.getColorModel(), master.copyData(null), master.isAlphaPremultiplied(), null);
212 frames.add(new ImageFrame(copy, delay, disposal));
214 if (disposal.equals("restoreToPrevious")) {
215 BufferedImage from = null;
216 for (int i = frameIndex - 1; i >= 0; i--) {
217 if (!frames.get(i).getDisposal().equals("restoreToPrevious") || frameIndex == 0) {
218 from = frames.get(i).image;
223 master = new BufferedImage(from.getColorModel(), from.copyData(null), from.isAlphaPremultiplied(), null);
224 masterGraphics = master.createGraphics();
225 masterGraphics.setBackground(new Color(0, 0, 0, 0));
226 } else if (disposal.equals("restoreToBackgroundColor")) {
227 masterGraphics.clearRect(x, y, image.getWidth(), image.getHeight());
232 return frames.toArray(new ImageFrame[frames.size()]);
235 public static class ImageFrame {
236 private final int delay;
237 public BufferedImage image;
238 private final String disposal;
240 public ImageFrame(BufferedImage image, int delay, String disposal) {
243 this.disposal = disposal;
246 public int getDelay() {
250 public String getDisposal() {