使用Apache PDFBox时,如何将图像集中到另一个图像中
我使用Apache提取字形图像。目前,此功能正常工作,但我遇到的问题是,某些字形图像不能适当地适合我正在创建的新图像的中心,无论我多么努力,我都不会得到结果!
请注意以下代码。我已经根据部分对他们评论了它们,以了解这些代码的工作过程。
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.PDVectorFont;
import org.apache.pdfbox.pdmodel.fontPane.PDFont;
import org.apache.pdfbox.pdmodel.fontPane.PDSimpleFont;
import org.apache.pdfbox.pdmodel.fontPane.PDType1CFont;
import org.apache.pdfbox.pdmodel.fontpane.FontPane;
import org.apache.pdfbox.preflight.font.SimpleFontValidator;
import org.apache.pdfbox.pdmodel.font.PDType1CFont;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.TableCellRenderer;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Iterator;
import org.apache.pdfbox.debugger.PDFDebugger;
import org.apache.pdfbox.debugger.ui.HighResolutionImageIcon;
public class GlyphExtractor {
private static final AffineTransform DEFAULT_TRANSFORM = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration().getDefaultTransform();
public static void main(String[] args) throws IOException{
String filename = "14010316.pdf";
//Load file as a pdfDocument
PDDocument document = PDDocument.load(new File(filename));
//Get the first page of file
PDPage page = document.getPage(0);
//Get all page resources from page one
PDResources pageResources = page.getResources();
//Get page font named F1 (this font is embeded into pdf as resource) and cast it to a font type
COSName f1Name = COSName.getPDFName("F1");
org.apache.pdfbox.pdmodel.font.PDFont fontF1 = pageResources.getFont(f1Name);
PDType1CFont fontPane = (PDType1CFont) fontF1;
//Iterate over all font glyphs and store it into an object
int totalAvailableGlyph = 0;
Object[][] glyphs = new Object[256][4];
for (int index = 0; index <= 255; index++)
{
glyphs[index][0] = index;
if (fontPane.getEncoding().contains(index) || fontPane.toUnicode(index) != null)
{
String glyphName = fontPane.getEncoding().getName(index);
glyphs[index][1] = glyphName;
glyphs[index][2] = fontPane.toUnicode(index);
try
{
if (fontPane instanceof PDVectorFont)
{
// using names didn't work with the file from PDFBOX-3445
glyphs[index][3] = ((PDVectorFont) fontPane).getPath(index);
}
else
{
// type 1 font isn't a vector font in 2.0
glyphs[index][3] = fontPane.getPath(glyphName);
}
}
catch (IOException ex)
{
}
totalAvailableGlyph++;
}
else
{
glyphs[index][1] = "None";
glyphs[index][2] = "None";
glyphs[index][3] = fontPane.getPath(".notdef");
}
}
//Iterate ove all glyphs and generate image for each glyph image
for (int index = 0; index <= 255; index++)
{
String glyphName = (String) glyphs[index][1];
if(glyphName == "None" || glyphName == ".notdef" || glyphName == "space"){
continue;
}
//Get the General path pf glyph from glyphs Object and get the 2D bound of it
GeneralPath path = (GeneralPath) glyphs[index][3];
Rectangle2D bounds2D = path.getBounds2D();
//Generate new image and save it into disk (into a folder named images)
BufferedImage bim = renderGlyph(path, bounds2D, 512, 512);
File outputfile = new File("./images", String.format("page%s-%s-%s.png", 0 + 1, index, glyphName));
ImageIO.write(bim, "png", outputfile);
}
System.out.println(totalAvailableGlyph);
}
//Render Glyphfs Function
private static BufferedImage renderGlyph(GeneralPath path, Rectangle2D bounds2D, int ImageWidth, int ImageHeight)
{
//Create New Buffer Image With Given Height and Width
BufferedImage bim = new BufferedImage(
ImageWidth,
ImageHeight,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) bim.getGraphics();
g.setBackground(Color.white);
g.clearRect(0, 0, bim.getWidth(), bim.getHeight());
double scale = 0.5;
// flip
g.scale(1, -1);
g.translate(0, -bim.getHeight());
// horizontal center
g.translate(((bim.getWidth() - bounds2D.getWidth() * scale) / 2) * DEFAULT_TRANSFORM.getScaleX(), 0);
// DEFAULT_TRANSFORM.getScaleX() & DEFAULT_TRANSFORM.getScaleY() is 1
g.scale(scale * DEFAULT_TRANSFORM.getScaleX(), scale * DEFAULT_TRANSFORM.getScaleY());
/**
* My Problem Is HERE...
* How to Calculate the best height for positioning glyph into buffred image?
*/
float finalHeight = (float) ((float) ((bim.getHeight() - bounds2D.getHeight()) / 2 ) + bounds2D.getHeight());
// Adjust for negative y min bound
g.translate(0, finalHeight - 50);
//finally add glyph to image and return the image binary file to save into disk
g.setColor(Color.black);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.fill(path);
g.dispose();
return bim;
}
}
I used Apache to extract glyph images. At the moment this feature works fine but the problem I have is that some of the glyph images do not fit properly in the center of the new image I am creating and no matter how hard I try I will not get results!
Please pay attention to the following codes. I have commented on them section by section to understand the working process of these codes.
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.PDVectorFont;
import org.apache.pdfbox.pdmodel.fontPane.PDFont;
import org.apache.pdfbox.pdmodel.fontPane.PDSimpleFont;
import org.apache.pdfbox.pdmodel.fontPane.PDType1CFont;
import org.apache.pdfbox.pdmodel.fontpane.FontPane;
import org.apache.pdfbox.preflight.font.SimpleFontValidator;
import org.apache.pdfbox.pdmodel.font.PDType1CFont;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.TableCellRenderer;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Iterator;
import org.apache.pdfbox.debugger.PDFDebugger;
import org.apache.pdfbox.debugger.ui.HighResolutionImageIcon;
public class GlyphExtractor {
private static final AffineTransform DEFAULT_TRANSFORM = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration().getDefaultTransform();
public static void main(String[] args) throws IOException{
String filename = "14010316.pdf";
//Load file as a pdfDocument
PDDocument document = PDDocument.load(new File(filename));
//Get the first page of file
PDPage page = document.getPage(0);
//Get all page resources from page one
PDResources pageResources = page.getResources();
//Get page font named F1 (this font is embeded into pdf as resource) and cast it to a font type
COSName f1Name = COSName.getPDFName("F1");
org.apache.pdfbox.pdmodel.font.PDFont fontF1 = pageResources.getFont(f1Name);
PDType1CFont fontPane = (PDType1CFont) fontF1;
//Iterate over all font glyphs and store it into an object
int totalAvailableGlyph = 0;
Object[][] glyphs = new Object[256][4];
for (int index = 0; index <= 255; index++)
{
glyphs[index][0] = index;
if (fontPane.getEncoding().contains(index) || fontPane.toUnicode(index) != null)
{
String glyphName = fontPane.getEncoding().getName(index);
glyphs[index][1] = glyphName;
glyphs[index][2] = fontPane.toUnicode(index);
try
{
if (fontPane instanceof PDVectorFont)
{
// using names didn't work with the file from PDFBOX-3445
glyphs[index][3] = ((PDVectorFont) fontPane).getPath(index);
}
else
{
// type 1 font isn't a vector font in 2.0
glyphs[index][3] = fontPane.getPath(glyphName);
}
}
catch (IOException ex)
{
}
totalAvailableGlyph++;
}
else
{
glyphs[index][1] = "None";
glyphs[index][2] = "None";
glyphs[index][3] = fontPane.getPath(".notdef");
}
}
//Iterate ove all glyphs and generate image for each glyph image
for (int index = 0; index <= 255; index++)
{
String glyphName = (String) glyphs[index][1];
if(glyphName == "None" || glyphName == ".notdef" || glyphName == "space"){
continue;
}
//Get the General path pf glyph from glyphs Object and get the 2D bound of it
GeneralPath path = (GeneralPath) glyphs[index][3];
Rectangle2D bounds2D = path.getBounds2D();
//Generate new image and save it into disk (into a folder named images)
BufferedImage bim = renderGlyph(path, bounds2D, 512, 512);
File outputfile = new File("./images", String.format("page%s-%s-%s.png", 0 + 1, index, glyphName));
ImageIO.write(bim, "png", outputfile);
}
System.out.println(totalAvailableGlyph);
}
//Render Glyphfs Function
private static BufferedImage renderGlyph(GeneralPath path, Rectangle2D bounds2D, int ImageWidth, int ImageHeight)
{
//Create New Buffer Image With Given Height and Width
BufferedImage bim = new BufferedImage(
ImageWidth,
ImageHeight,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) bim.getGraphics();
g.setBackground(Color.white);
g.clearRect(0, 0, bim.getWidth(), bim.getHeight());
double scale = 0.5;
// flip
g.scale(1, -1);
g.translate(0, -bim.getHeight());
// horizontal center
g.translate(((bim.getWidth() - bounds2D.getWidth() * scale) / 2) * DEFAULT_TRANSFORM.getScaleX(), 0);
// DEFAULT_TRANSFORM.getScaleX() & DEFAULT_TRANSFORM.getScaleY() is 1
g.scale(scale * DEFAULT_TRANSFORM.getScaleX(), scale * DEFAULT_TRANSFORM.getScaleY());
/**
* My Problem Is HERE...
* How to Calculate the best height for positioning glyph into buffred image?
*/
float finalHeight = (float) ((float) ((bim.getHeight() - bounds2D.getHeight()) / 2 ) + bounds2D.getHeight());
// Adjust for negative y min bound
g.translate(0, finalHeight - 50);
//finally add glyph to image and return the image binary file to save into disk
g.setColor(Color.black);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.fill(path);
g.dispose();
return bim;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论