package edu.isi.bmkeg.lapdf.utils;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.TextAttribute;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.AttributedString;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import javax.imageio.ImageIO;
import edu.isi.bmkeg.lapdf.controller.LapdfMode;
import edu.isi.bmkeg.lapdf.model.Block;
import edu.isi.bmkeg.lapdf.model.ChunkBlock;
import edu.isi.bmkeg.lapdf.model.PageBlock;
import edu.isi.bmkeg.lapdf.model.WordBlock;
import edu.isi.bmkeg.lapdf.model.ordering.SpatialOrdering;
public class PageImageOutlineRenderer {
private static TreeMap<Integer, String> colorMap = new TreeMap<Integer, String>();
private static TreeMap<String, Integer> countMap = new TreeMap<String, Integer>();
private static final int TYPE_UNCLASSIFIED_COLOR_CODE = 0xFBF5EF;
public static void createPageImage(PageBlock page, File outputFile, String label, int mode) throws IOException {
int width = page.getPageBoxWidth();
int height = page.getPageBoxHeight();
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
image.getGraphics().setColor(Color.white);
image.getGraphics().fillRect(0, 0, width, height);
image.getGraphics().setColor(Color.red);
drawWord(width / 2 - 50, 10, image, Color.black,
label + ":" + page.getPageNumber(), 10);
List<ChunkBlock> cbList = page.getAllChunkBlocks(SpatialOrdering.MIXED_MODE);
List<Block> list = new ArrayList<Block>(cbList);
// renderBlockPerImage(list, image, fileName);
renderBlockByColor(list, image, mode);
List<WordBlock> wbList = page.getAllWordBlocks(SpatialOrdering.MIXED_MODE);
list = new ArrayList<Block>(wbList);
renderBlockByColor(list, image, mode);
ImageIO.write(image, "png", outputFile);
}
private static void renderBlockByColor(
List<Block> entityList,
BufferedImage image, int mode) {
for (Block block : entityList) {
if (block instanceof ChunkBlock) {
ChunkBlock chunky = (ChunkBlock) block;
Integer colorCode = colorDecider(chunky.getType());
if (colorMap.get(colorCode) == null) {
if (colorCode == TYPE_UNCLASSIFIED_COLOR_CODE)
colorMap.put(colorCode, Block.TYPE_UNCLASSIFIED);
else
colorMap.put(colorCode, chunky.getType());
}
if (colorCode == TYPE_UNCLASSIFIED_COLOR_CODE) {
if (countMap.get(Block.TYPE_UNCLASSIFIED) == null) {
countMap.put(Block.TYPE_UNCLASSIFIED, 1);
} else {
countMap.put(Block.TYPE_UNCLASSIFIED,
countMap.get(Block.TYPE_UNCLASSIFIED) + 1);
}
} else {
if (countMap.get(chunky.getType()) == null) {
countMap.put(chunky.getType(), 1);
} else {
countMap.put(chunky.getType(),
countMap.get(chunky.getType()) + 1);
}
}
drawRectangle(chunky.getX1(), chunky.getY1(),
chunky.getWidth(), chunky.getHeight(), image,
Color.red, chunky, mode);
String text = chunky.getMostPopularWordFont() + ";" + chunky.getMostPopularWordStyle();
if( mode != LapdfMode.BLOCK_ONLY )
text = chunky.getType();
drawWord( chunky.getX1() - 20,
chunky.getY1() ,
image,
Color.black,
text, 12);
} else if (block != null) {
WordBlock wordBlock = (WordBlock) block;
ChunkBlock chunky = (ChunkBlock) wordBlock.getContainer();
Integer colorCode = (mode == 1) ? colorDecider(chunky.getType())
: 0x000000;
drawRectangle(wordBlock.getX1() + 2, wordBlock.getY1() + 2,
wordBlock.getWidth() - 4, wordBlock.getHeight() - 4,
image, new Color(colorCode), block, mode);
if( wordBlock.getFontStyle() != null) {
String text = wordBlock.getFontStyle();
text = text.substring(10, text.length()-2);
drawWord( wordBlock.getX1(),
wordBlock.getY1() + wordBlock.getHeight(),
image,
Color.black,
text, 6);
}
}
}
}
private static int colorDecider(String type) {
if (Block.TYPE_METHODS_HEADING.equals(type)) {
return 0x0000ff;
} else if (Block.TYPE_METHODS_BODY.equals(type)) {
return 0x008000;
} else if (Block.TYPE_METHODS_SUBTITLE.equals(type)) {
return 0x00bfff;
} else if (Block.TYPE_RESULTS_HEADING.equals(type)) {
return 0x800080;
} else if (Block.TYPE_RESULTS_BODY.equals(type)) {
return 0x800000;
} else if (Block.TYPE_RESULTS_SUBTITLE.equals(type)) {
return 0x7cfc00;
} else if (Block.TYPE_REFERENCES_HEADING.equals(type)) {
return 0xffff00;
} else if (Block.TYPE_REFERENCES_BODY.equals(type)) {
return 0xff69b4;
} else if (Block.TYPE_DISCUSSION_HEADING.equals(type)) {
return 0xff0000;
} else if (Block.TYPE_DISCUSSION_BODY.equals(type)) {
return 0xfa8072;
} else if (Block.TYPE_DISCUSSION_SUBTITLE.equals(type)) {
return 0xff4500;
} else if (Block.TYPE_CONCLUSIONS_HEADING.equals(type)) {
return 0xb8860b;
} else if (Block.TYPE_CONCLUSIONS_BODY.equals(type)) {
return 0xbc8f8f;
} else if (Block.TYPE_CONCLUSIONS_SUBTITLE.equals(type)) {
return 0xbdb76b;
} else if (Block.TYPE_ACKNOWLEDGEMENTS_HEADING.equals(type)) {
return 0x4b0082;
} else if (Block.TYPE_ACKNOWLEDGEMENTS_BODY.equals(type)) {
return 0x556b2f;
} else if (Block.TYPE_ABSTRACT_HEADING.equals(type)) {
return 0xA9D0F5;
} else if (Block.TYPE_ABSTRACT_BODY.equals(type)) {
return 0x00FFFF;
} else if (Block.TYPE_TITLE.equals(type)) {
return 0xdc143c;
} else if (Block.TYPE_AUTHORS.equals(type)) {
return 0xffa500;
} else if (Block.TYPE_INTRODUCTION_HEADING.equals(type)) {
return 0xcd853f;
} else if (Block.TYPE_INTRODUCTION_BODY.equals(type)) {
return 0xd2691e;
} else if (Block.TYPE_INTRODUCTION_SUBTITLE.equals(type)) {
return 0xd2b48c;
} else if (Block.TYPE_SUPPORTING_INFORMATION_HEADING.equals(type)) {
return 0x8b4513;
} else if (Block.TYPE_SUPPORTING_INFORMATION_BODY.equals(type)) {
return 0x8fbc8f;
} else if (Block.TYPE_SUPPORTING_INFORMATION_SUBTITLE.equals(type)) {
return 0x90ee90;
} else if (Block.TYPE_FIGURE_LEGEND.equals(type)) {
return 0x000000;
} else if (Block.TYPE_AFFLIATION.equals(type)) {
return TYPE_UNCLASSIFIED_COLOR_CODE;
} else if (Block.TYPE_HEADER.equals(type)) {
return TYPE_UNCLASSIFIED_COLOR_CODE;
} else if (Block.TYPE_FOOTER.equals(type)) {
return TYPE_UNCLASSIFIED_COLOR_CODE;
} else if (Block.TYPE_KEYWORDS.equals(type)) {
return TYPE_UNCLASSIFIED_COLOR_CODE;
} else if (Block.TYPE_TABLE.equals(type)) {
return TYPE_UNCLASSIFIED_COLOR_CODE;
} else if (Block.TYPE_CITATION.equals(type)) {
return TYPE_UNCLASSIFIED_COLOR_CODE;
} else {
return TYPE_UNCLASSIFIED_COLOR_CODE;
}
}
private static void drawRectangle(int x, int y, int width, int height,
BufferedImage image, Color color, Block block, int mode) {
Graphics2D graphics = image.createGraphics();
graphics.setPaint(color);
Rectangle rect = new Rectangle(x, y, width, height);
if ( block instanceof WordBlock && mode == LapdfMode.BLOCK_ONLY ) {
graphics.draw(rect);
graphics.fill(rect);
} else {
graphics.draw(rect);
}
}
private static void drawWord(int x, int y, int width, int height,
BufferedImage image, Color color, WordBlock word) {
Graphics2D graphics = image.createGraphics();
Font plainFont = new Font(word.getFont(), Font.PLAIN, word.getHeight());
AttributedString as = new AttributedString(word.getWord());
as.addAttribute(TextAttribute.FONT, plainFont);
graphics.setPaint(color);
graphics.drawString(as.getIterator(), x, y);
}
private static void drawWord(
int x, int y,
BufferedImage image,
Color color,
String word,
int size) {
Graphics2D graphics = image.createGraphics();
Font plainFont = new Font(Font.SANS_SERIF, Font.PLAIN, size);
AttributedString as = new AttributedString(word);
as.addAttribute(TextAttribute.FONT, plainFont);
graphics.setPaint(color);
graphics.drawString(as.getIterator(), x, y);
}
public static void createReport(String fileName) {
if (colorMap.size() == 0 || countMap.size() == 0) {
throw new IllegalStateException(
"Before calling this method you should use createPageImage to draw the individual pages");
}
BufferedImage image = new BufferedImage(500, 800,
BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
image.getGraphics().setColor(Color.white);
image.getGraphics().fillRect(0, 0, 500, 800);
String sectionType;
int x = 20;
int y = 20;
Font plainFont = new Font(Font.SANS_SERIF, Font.PLAIN, 20);
for (Integer color : colorMap.keySet()) {
sectionType = colorMap.get(color);
Shape circle = new Ellipse2D.Float(x, y, 20, 20);
graphics.setPaint(new Color(color));
graphics.draw(circle);
graphics.fill(circle);
graphics.setColor(Color.black);
AttributedString as = new AttributedString(sectionType);
as.addAttribute(TextAttribute.FONT, plainFont);
graphics.drawString(as.getIterator(), x + 22, y + 20);
as = new AttributedString(countMap.get(sectionType) + "");
graphics.drawString(as.getIterator(), 380, y + 20);
x = 20;
y = y + 24;
}
try {
File outputfile = new File(fileName);
ImageIO.write(image, "png", outputfile);
} catch (IOException e) {
}
colorMap.clear();
countMap.clear();
}
}