Hi,
I have JPEG-images which present pages from an original text document.
The original paper documents are OCR-ed and in the output of the OCR I
get the coordinates of every word. The user of my application will be
able to search for text and the search results will be presented as a
JPEG of the page, with the word the user searched for highlighted.
At the moment I'm experimenting with the highlighting of the text. I
tried the following (see code below), but I'm not really sure I'm on the
right track.
- Has anyone suggestions for a better approach?
- I saw some examples with ByteLookupTables. Would that be a better
solution for highlighting?
- I'm a bit worried about the performance. Any ideas on that?
- The version I post below has a color problem. I fiddled with the
AlphaComposite value, but the original JPEG is either too dark or too
pale compared to the orginal.
- The coordinates are from Prime Recognition OCR-software. They say:
"the coordinates are in BMU units. One BMU is 1/1200 of an inch". Trial
and error with an example showed me that dividing their coordinates by
4 gave me the right coordinates for the word in Java. Would this always
be correct or is there a more universal way of converting the
OCR-coordinates to Java-coordinates? I read somewhere that Java
coordinates are 72 units (pixels) per inch, so I can't understand how my
division by 4 can give me the right result, but it does :-)
Any help will be greatly appreciated!
Kind regards,
Marian
marian dot hellema at kb dot nl
My code below
============================================================
import java.awt.*;
import java.awt.event.*;
import java.awt.color.*;
import com.sun.image.codec.jpeg.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.geom.GeneralPath;
import java.io.*;
import javax.swing.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.net.*;
import javax.imageio.*;
import javax.imageio.stream.*;
public class Test{
public static void main(String[] args) throws IOException {
Image img = Toolkit.getDefaultToolkit().getImage("00002.jpg");
JFrame f = new JFrame("Proef");
try {
MediaTracker tracker = new MediaTracker(f);
tracker.addImage(img, 0);
tracker.waitForID(0);
} catch (Exception e) {}
// width and height hard-coded for the time being
int width = 1000;
int height = 1000;
BufferedImage bi = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D biContext = bi.createGraphics();
biContext.clearRect(0, 0, width, height);
AlphaComposite ac =
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.9f);
biContext.setComposite(ac);
biContext.drawImage(img, new AffineTransform(), null);
biContext.setColor(new Color(255, 255, 121));
// yellow color for the highlighted text
biContext.fillRect(456/4, 2752/4, (888-456)/4, (2880-2752)/4);
// coordinates hard-coded for the time being
// coordinates from OCR are 456, 888, 2752, 2880
// division by 4 gives the Java coordinates
biContext.dispose();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JLabel(new ImageIcon(bi)));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
======================================================
End of code
Chris Smith - 28 Jun 2005 20:10 GMT
> - The coordinates are from Prime Recognition OCR-software. They say:
> "the coordinates are in BMU units. One BMU is 1/1200 of an inch". Trial
[quoted text clipped - 4 lines]
> coordinates are 72 units (pixels) per inch, so I can't understand how my
> division by 4 can give me the right result, but it does :-)
Just answering this part of your question for now.
Java does not always work in 72 dpi, so I don't know where you got that
information from. It is senseless to try to identify a pixel resolution
for "Java". Java can work with images in all sorts of resolutions. It
appears that the images you're getting are in 300 dpi resolution. That
can definitely vary depending on many factors, most notably the settings
of your scanner when you scanned the image.
Determining the resolution of an image is interesting, though. ImageIO
(part of the standard library as of 1.4, IIRC) provides the basic tools,
but it doesn't seem to properly interpret JPEG resolutions in the
standard cross-format encoding. As a result, you need to use JPEG-
specific code to get the values. It looks something like this:
public class Test
{
public static void main(String[] args)
throws Exception
{
JFileChooser chooser = new JFileChooser();
int result = chooser.showOpenDialog(null);
if (result != JFileChooser.APPROVE_OPTION) return;
File f = chooser.getSelectedFile();
FileImageInputStream stream = new FileImageInputStream(f);
Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);
assert readers.hasNext();
ImageReader r = readers.next();
r.setInput(stream);
final int RES_ASPECT = 0;
final int RES_INCHES = 1;
final int RES_CENTIMETERS = 2;
double xRes = Double.NaN, yRes = Double.NaN;
IIOMetadata meta = r.getImageMetadata(0);
Element topNode = (Element)
meta.getAsTree("javax_imageio_jpeg_image_1.0");
NodeList nodeList = topNode.getElementsByTagName("app0JFIF");
if (nodeList.getLength() == 1)
{
Element app0 = (Element) nodeList.item(0);
if (app0.hasAttribute("resUnits"))
{
int units = Integer.parseInt(
app0.getAttribute("resUnits"));
if (units != RES_ASPECT)
{
int xd = Integer.parseInt(
app0.getAttribute("Xdensity"));
int yd = Integer.parseInt(
app0.getAttribute("Ydensity"));
if (units == RES_INCHES)
{
xRes = xd;
yRes = yd;
}
else if (units == RES_CENTIMETERS)
{
xRes = xd * 2.54;
yRes = xd * 2.54;
}
}
}
}
System.out.println(xRes + " x " + yRes);
}
}
Not all JPEG files include resolution information. When this is the
case, they are often interpreted by various programs as either 72 dpi or
96 dpi.

Signature
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
Roedy Green - 29 Aug 2005 08:24 GMT
>Java does not always work in 72 dpi,
I think what he is referring to is that 12 point type in Java is 12
pixels tall. A point/pixel in Java is thus nominally 1/72 of an inch.

Signature
Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.
Chris Smith - 29 Aug 2005 16:52 GMT
> I think what he is referring to is that 12 point type in Java is 12
> pixels tall. A point/pixel in Java is thus nominally 1/72 of an inch.
No, I'm referring to the fact that the resolution at which an image is
printed depends on how you print it. That's all.

Signature
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
Chris Smith - 28 Jun 2005 20:12 GMT
> - The version I post below has a color problem. I fiddled with the
> AlphaComposite value, but the original JPEG is either too dark or too
> pale compared to the orginal.
Have you tried drawing the original JPEG before setting an
AlphaComposite? You should only need to perform alpha-compositing for
the highlight, not the original image.

Signature
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
Marian Hellema - 29 Jun 2005 19:12 GMT
Dear Chris,
Thanks a lot for your postings! You're right: I changed my code to draw
the image before setting the AlphaComposite and I removed the
clearRect() line; now the colors look fine.
Your code to find out the resolution of the JPEG looks interesting. I
did not yet really try it, but it might be useful later on.
About my assumption that Java works in 72 dpi, I got that from an
article on
http://java.sun.com/developer/technicalArticles/GUI/java2d/java2dpart1.html
As I understand it now, this applies to the user space, where I thought
my program was working, but apperently not. Never mind, as long as it
works :-)
Again, thank you for your help!
Best regards,
Marian
>>- The version I post below has a color problem. I fiddled with the
>>AlphaComposite value, but the original JPEG is either too dark or too
[quoted text clipped - 3 lines]
> AlphaComposite? You should only need to perform alpha-compositing for
> the highlight, not the original image.
Roedy Green - 29 Aug 2005 08:22 GMT
>so I can't understand how my
>division by 4 can give me the right result, but it does
One thing you really have to watch out for in Java is scaling an image
inadvertently.

Signature
Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.