Cannot find symbol - variable mText - java

Hey all i have been writing some code, it allows a user to select a file, a txt file, it then reads the contents of the file and then sends the contents to a printer this case a hp 8600, but on compling i get an error, Cannot find symbol - variable mText, why is this, it should be retriving mText from above as this now should contain all the data from the txt file, what am i doing wrong ?
code:
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.print.*;
import java.text.*;
import java.io.*;
import javax.swing.*;
public class PrintText implements Printable {
// Below the code will allow the user to select a file and then print out the contents of the file
public static void main(String[] args) throws IOException {
//selects the file
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);
File file = chooser.getSelectedFile();
String filename = file.getName();
//System.out.println("You have selected: " + filename); testing to see if file seleected was right
String path = file.getAbsolutePath();
//Reads contents of file into terminal
//FileReader fr = new FileReader("filename");
// FileReader fr = new FileReader("D:/Documents/" + "filename"));
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String mText;
while((mText = br.readLine()) != null) {
//Displays the contents of the file in terminal
System.out.println(mText);
}
//fr.close();
}
//private static final String mText =
// "This is a test to see if this text will be printed "; //This works perfectly fine
private static final AttributedString mStyledText = new AttributedString(mText);
/**
* Print a single page containing some sample text.
*/
static public void printer(String args[]) {
/* Get the representation of the current printer and
* the current print job.
*/
PrinterJob printerJob = PrinterJob.getPrinterJob();
/* Build a book containing pairs of page painters (Printables)
* and PageFormats. This example has a single page containing
* text.
*/
Book book = new Book();
book.append(new PrintText(), new PageFormat());
/* Set the object to be printed (the Book) into the PrinterJob.
* Doing this before bringing up the print dialog allows the
* print dialog to correctly display the page range to be printed
* and to dissallow any print settings not appropriate for the
* pages to be printed.
*/
printerJob.setPageable(book);
/* Show the print dialog to the user. This is an optional step
* and need not be done if the application wants to perform
* 'quiet' printing. If the user cancels the print dialog then false
* is returned. If true is returned we go ahead and print.
*/
boolean doPrint = printerJob.printDialog();
if (doPrint) {
try {
printerJob.print();
} catch (PrinterException exception) {
System.err.println("Printing error: " + exception);
}
}
}
/**
* Print a page of text.
*/
public int print(Graphics g, PageFormat format, int pageIndex) {
/* We'll assume that Jav2D is available.
*/
Graphics2D g2d = (Graphics2D) g;
/* Move the origin from the corner of the Paper to the corner
* of the imageable area.
*/
g2d.translate(format.getImageableX(), format.getImageableY());
/* Set the text color.
*/
g2d.setPaint(Color.black);
/* Use a LineBreakMeasurer instance to break our text into
* lines that fit the imageable area of the page.
*/
Point2D.Float pen = new Point2D.Float();
AttributedCharacterIterator charIterator = mStyledText.getIterator();
LineBreakMeasurer measurer = new LineBreakMeasurer(charIterator, g2d.getFontRenderContext());
float wrappingWidth = (float) format.getImageableWidth();
while (measurer.getPosition() < charIterator.getEndIndex()) {
TextLayout layout = measurer.nextLayout(wrappingWidth);
pen.y += layout.getAscent();
float dx = layout.isLeftToRight()? 0 : (wrappingWidth - layout.getAdvance());
layout.draw(g2d, pen.x + dx, pen.y);
pen.y += layout.getDescent() + layout.getLeading();
}
return Printable.PAGE_EXISTS;
}
}

Currently mText is only defined within the scope of the main method.
You would need to make mText a static class variable is you wish to use it in the constructor of mStyledText:
private static String mText;
Having non-final static class variables is considered bad practice, however—why not create AttributedString in the print method just when its needed:
AttributedString mStyledText = new AttributedString(mText);
Also you have a lot of functionality in the main method. I would move it to a class instance method where you could avoid using any static variables altogether.

Related

Print pdf file with JAVA Pdfbox scale and auto orientation like acrobat reader

I want to print pdf file that will be like the acrobat reader printing.
i tried with this code:
public static void print3() throws PrinterException, IOException {
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
if(service != null)
{
PrintService selection = ServiceUI.printDialog(null, 200, 200, services, service, null, attrs);
PrinterJob job = PrinterJob.getPrinterJob();
PDDocument document = PDDocument.load(new File("C:\\Temp\\test.pdf"));
PDFPageable pageAble = new PDFPageable(document, Orientation.AUTO);
job.setPageable(pageAble);
attrs.remove(OrientationRequested.class);
job.setPrintService(selection);
job.print(attrs);
}
}
but the text go out of the page:
if i print this pdf with acrobat reader with this options:
its working perfect.
i want to know how can i print the page like the acrobat reader with java?
its seems that the auto orientation working because its printing on landscape like he needs, but how can i scale like the acrobat to 54% automatically ?
tnx a lot
Edit:
i tried to create custom pageable by taking the source code of PDFPageable and change the scale in the getPrintable() method like this:
import java.awt.RenderingHints;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.printing.Orientation;
import org.apache.pdfbox.printing.Scaling;
public final class MyPageable extends Book
{
private final PDDocument document;
private final boolean showPageBorder;
private final float dpi;
private final Orientation orientation;
private boolean subsamplingAllowed = false;
private RenderingHints renderingHints = null;
/**
* Creates a new PDFPageable.
*
* #param document the document to print
*/
public MyPageable(PDDocument document)
{
this(document, Orientation.AUTO, false, 0);
}
/**
* Creates a new PDFPageable with the given page orientation.
*
* #param document the document to print
* #param orientation page orientation policy
*/
public MyPageable(PDDocument document, Orientation orientation)
{
this(document, orientation, false, 0);
}
/**
* Creates a new PDFPageable with the given page orientation and with optional page borders
* shown. The image will be rasterized at the given DPI before being sent to the printer.
*
* #param document the document to print
* #param orientation page orientation policy
* #param showPageBorder true if page borders are to be printed
*/
public MyPageable(PDDocument document, Orientation orientation, boolean showPageBorder)
{
this(document, orientation, showPageBorder, 0);
}
/**
* Creates a new PDFPageable with the given page orientation and with optional page borders
* shown. The image will be rasterized at the given DPI before being sent to the printer.
*
* #param document the document to print
* #param orientation page orientation policy
* #param showPageBorder true if page borders are to be printed
* #param dpi if non-zero then the image will be rasterized at the given DPI
*/
public MyPageable(PDDocument document, Orientation orientation, boolean showPageBorder,
float dpi)
{
this.document = document;
this.orientation = orientation;
this.showPageBorder = showPageBorder;
this.dpi = dpi;
}
/**
* Get the rendering hints.
*
* #return the rendering hints or null if none are set.
*/
public RenderingHints getRenderingHints()
{
return renderingHints;
}
/**
* Set the rendering hints. Use this to influence rendering quality and speed. If you don't set
* them yourself or pass null, PDFBox will decide <b><u>at runtime</u></b> depending on the
* destination.
*
* #param renderingHints
*/
public void setRenderingHints(RenderingHints renderingHints)
{
this.renderingHints = renderingHints;
}
/**
* Value indicating if the renderer is allowed to subsample images before drawing, according to
* image dimensions and requested scale.
*
* Subsampling may be faster and less memory-intensive in some cases, but it may also lead to
* loss of quality, especially in images with high spatial frequency.
*
* #return true if subsampling of images is allowed, false otherwise.
*/
public boolean isSubsamplingAllowed()
{
return subsamplingAllowed;
}
/**
* Sets a value instructing the renderer whether it is allowed to subsample images before
* drawing. The subsampling frequency is determined according to image size and requested scale.
*
* Subsampling may be faster and less memory-intensive in some cases, but it may also lead to
* loss of quality, especially in images with high spatial frequency.
*
* #param subsamplingAllowed The new value indicating if subsampling is allowed.
*/
public void setSubsamplingAllowed(boolean subsamplingAllowed)
{
this.subsamplingAllowed = subsamplingAllowed;
}
#Override
public int getNumberOfPages()
{
return document.getNumberOfPages();
}
/**
* {#inheritDoc}
*
* Returns the actual physical size of the pages in the PDF file. May not fit the local printer.
*/
#Override
public PageFormat getPageFormat(int pageIndex)
{
PDPage page = document.getPage(pageIndex);
PDRectangle mediaBox = MyPrintable.getRotatedMediaBox(page);
PDRectangle cropBox = MyPrintable.getRotatedCropBox(page);
// Java does not seem to understand landscape paper sizes, i.e. where width > height, it
// always crops the imageable area as if the page were in portrait. I suspect that this is
// a JDK bug but it might be by design, see PDFBOX-2922.
//
// As a workaround, we normalise all Page(s) to be portrait, then flag them as landscape in
// the PageFormat.
Paper paper;
boolean isLandscape;
if (mediaBox.getWidth() > mediaBox.getHeight())
{
// rotate
paper = new Paper();
paper.setSize(mediaBox.getHeight(), mediaBox.getWidth());
paper.setImageableArea(cropBox.getLowerLeftY(), cropBox.getLowerLeftX(),
cropBox.getHeight(), cropBox.getWidth());
isLandscape = true;
}
else
{
paper = new Paper();
paper.setSize(mediaBox.getWidth(), mediaBox.getHeight());
paper.setImageableArea(cropBox.getLowerLeftX(), cropBox.getLowerLeftY(),
cropBox.getWidth(), cropBox.getHeight());
isLandscape = false;
}
PageFormat format = new PageFormat();
format.setPaper(paper);
// auto portrait/landscape
switch (orientation)
{
case AUTO:
format.setOrientation(isLandscape ? PageFormat.LANDSCAPE : PageFormat.PORTRAIT);
break;
case LANDSCAPE:
format.setOrientation(PageFormat.LANDSCAPE);
break;
case PORTRAIT:
format.setOrientation(PageFormat.PORTRAIT);
break;
default:
break;
}
return format;
}
#Override
public Printable getPrintable(int i)
{
if (i >= getNumberOfPages())
{
throw new IndexOutOfBoundsException(i + " >= " + getNumberOfPages());
}
MyPrintable printable = new MyPrintable(document, Scaling.SHRINK_TO_FIT, showPageBorder, dpi);
printable.setSubsamplingAllowed(subsamplingAllowed);
printable.setRenderingHints(renderingHints);
return printable;
}
}
but the result is the same.

Programatically added picture in PDF picture field not being displayed

I have created a PDF with Adobe, which contains an image field called "logo"
Now if i want to add a picture using PDFBox it won't be displayed in the created pdf.
However no error message is thrown and debugging looks completely fine with a correctly created PDImageXObject object.
The used code is mostly adapted from this question:
public static void setImageField(PDDocument pdfDocument, PDAcroForm acroForm, String fieldKey, byte[] imageData)
{
final PDField retrievedField = acroForm.getField(fieldKey);
if (!(retrievedField instanceof PDPushButton)) {
throw new RuntimeException("The field: " + fieldKey + " is not of the correct type");
}
LOGGER.info("Received field: " + retrievedField.getPartialName()); // correct field is being logged
final PDPushButton imageField = (PDPushButton) retrievedField;
final List<PDAnnotationWidget> fieldWidgets = imageField.getWidgets(); // it has exactly one widget, which would be the action to set the image
if (fieldWidgets == null || fieldWidgets.size() <= 0) {
throw new RuntimeException("Misconfiguration for field: " + fieldKey + ", it has no widgets(actions)");
}
final PDAnnotationWidget imageWidget = fieldWidgets.get(0);
PDImageXObject imageForm;
try {
// This test data is resized to be smaller than the bounding box of the image element in the PDF. Just for testing purposes
final String testImage = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAARUlEQVR42u3PMREAAAgEIO2fzkRvBlcPGtCVTD3QIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIXC7VGjKHva+IvAAAAAElFTkSuQmCC";
final byte[] testData = Base64.getDecoder().decode(testImage);
imageForm = PDImageXObject.createFromByteArray(pdfDocument, testData, "logo"); // imageForm is being populated with data and no error thrown
}
catch (IOException e) {
throw new RuntimeException("Error creating Image from image data", e);
}
final float imageScaleRatio = (float) (imageForm.getHeight() / imageForm.getWidth());
final PDRectangle imagePosition = getFieldArea(imageField);
LOGGER.info("Received image position: " + imagePosition.toString());
// Retrieve the height and width and position of the rectangle where the picture will be
final float imageHeight = imagePosition.getHeight();
LOGGER.info("Image height: " + imageHeight);
final float imageWidth = imageHeight / imageScaleRatio;
LOGGER.info("Image width: " + imageWidth);
final float imageXPosition = imagePosition.getLowerLeftX();
LOGGER.info("Image X position: " + imageXPosition);
final float imageYPosition = imagePosition.getLowerLeftY();
LOGGER.info("Image Y position: " + imageYPosition);
final PDAppearanceStream documentAppearance = new PDAppearanceStream(pdfDocument);
documentAppearance.setResources(new PDResources()); // not sure why this is done
// Weird "bug" in pdfbox forces to create the contentStream always after the object to add
try (PDPageContentStream documentContentStream = new PDPageContentStream(pdfDocument, documentAppearance)) {
documentContentStream.drawImage(imageForm, imageXPosition, imageYPosition, imageWidth, imageHeight);
}
catch (IOException e) {
throw new RuntimeException("Error drawing the picture in the document", e);
}
// Setting the boundary box is mandatory for the image field! Do not remove or the flatten call on the acroform will NPE
documentAppearance.setBBox(new PDRectangle(imageXPosition, imageYPosition, imageWidth, imageHeight));
// Apply the appearance settings of the document onto the image widget ( No border )
setImageAppearance(imageWidget, documentAppearance);
// This code is normally somewhere else but for SO copied in this method to show how the pdf is being created
acroForm.flatten();
AccessPermission ap = new AccessPermission();
ap.setCanModify(false);
ap.setCanExtractContent(false);
ap.setCanFillInForm(false);
ap.setCanModifyAnnotations(false);
ap.setReadOnly();
StandardProtectionPolicy spp = new StandardProtectionPolicy("", "", ap);
spp.setEncryptionKeyLength(PdfBuildConstants.ENCRYPTION_KEY_LENTGH);
pdfDocument.protect(spp);
pdfDocument.save(pdfFile);
pdfDocument.close();
}
/**
* Applies the appearance settings of the document onto the widget to ensure a consistent look of the document.
*
* #param imageWidget The {#link PDAnnotationWidget Widget} to apply the settings to
* #param documentAppearance The {#link PDAppearanceStream Appearance settings} of the document
*/
private static void setImageAppearance(final PDAnnotationWidget imageWidget,
final PDAppearanceStream documentAppearance)
{
PDAppearanceDictionary widgetAppearance = imageWidget.getAppearance();
if (widgetAppearance == null) {
widgetAppearance = new PDAppearanceDictionary();
imageWidget.setAppearance(widgetAppearance);
}
widgetAppearance.setNormalAppearance(documentAppearance);
}
/**
* Retrieves the dimensions of the given {#link PDField Field} and creates an {#link PDRectangle Rectangle} with the
* same dimensions.
*
* #param field The {#link PDField Field} to create the rectangle for
* #return The created {#link PDRectangle Rectangle} with the dimensions of the field
*/
private static PDRectangle getFieldArea(PDField field) {
final COSDictionary fieldDictionary = field.getCOSObject();
final COSBase fieldAreaValue = fieldDictionary.getDictionaryObject(COSName.RECT);
if (!(fieldAreaValue instanceof COSArray)) {
throw new RuntimeException("The field: " + field.getMappingName() + " has no position values");
}
final COSArray fieldAreaArray = (COSArray) fieldAreaValue;
return new PDRectangle(fieldAreaArray);
}
I also looked at other questions such as this, but I can't use PDJpeg since it is not available in the current version. Additionally the original image to use can be anything from jpeg,png to gif.
I validated that the position and dimension variables being logged have the same value as the image field in the pdf file. (properties of the field)
UPDATE:
Here is an example zip containing the template pdf and the generated pdf which fills in the form fields: file upload or Dropbox
The example picture was a 50x50 png with plain green color generated from online png pixel

How to remove text from Barcode image

I have written a code which can generate a bar-code with respect to String codeText = "1104006"; and also can read data from that bar-code. But the problem is, while generating a bar-code below the bar-code it also write the text (codeText). How can I remove the human readable text, circled red in example?
public class Main {
private static String strBarFolder = ("C:\\Users\\Jobayer__\\Desktop\\");
public static void main(String[] args) {
String codeText = "1104006";
String strImageFile = ("barcode.jpg");
BarCodeBuilder builder = new BarCodeBuilder(Symbology.CODE39STANDARD, codeText);
builder.save(strBarFolder + strImageFile);
System.out.println("Successfully Done");
Image img = Toolkit.getDefaultToolkit().getImage(strBarFolder + strImageFile);
BarCodeReader reader = new BarCodeReader(img, BarCodeReadType.Code39Standard);
while(reader.read()){
System.out.println("Code Text Found: " + reader.getCodeText());
}
reader.close();
}
}
Get into the Aspose source code (if it's allowable) and comment out the drawString() method which is drawing the text to the image OR modify the bar code image by drawing a white rectangle with fillRect() over the text area(s) of the image.
Below is a small runnable console application I quickly whipped up that performs the latter. It is based off of the Bar Code image you provided:
package barcodetextcoverup;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.imageio.ImageIO;
public class BarCodeTextCoverUp {
public static void main(String[] args) {
startTextCover();
}
private static void startTextCover() {
Scanner scnr = new Scanner(System.in);
String userInput = "";
while (!userInput.equalsIgnoreCase("quit")) {
System.out.println("\nEnter the path and file name to the Bar Code image file\n"
+ "to modify or enter quit to exit:");
userInput = scnr.nextLine();
if (userInput.equalsIgnoreCase("quit")) { break; }
// opening a bar code image from disk
BufferedImage src = null;
try {
src = ImageIO.read(new File(userInput));
int iWidth = src.getWidth();
int iHeight = src.getHeight();
// Modify the image...
Graphics2D g2 = src.createGraphics();
g2.setColor(Color.WHITE);
//Cover the text: Aspose.Demo
g2.fillRect(0, 0, 150, 30);
// Cover the codeText at bottom of Bar Code
g2.fillRect((iWidth/2) - 75, iHeight - 40, 150, 35);
g2.dispose();
System.out.println("\nEnter a NEW path and file name for the modified Bar Code image.\n"
+ "You can use the same file name just change the extention to .png:");
userInput = scnr.nextLine();
// If nothing is supplied then the modifications are not saved.
if (!userInput.equals("")) {
ImageIO.write((RenderedImage) src, "PNG", new File(userInput));
}
System.out.println("----------------------------------------------------------------------");
} catch (IOException ex) { }
}
}
}
Set this property:
builder.CodeLocation = CodeLocation.None;
Setting CodeLocation to None will hide the barcode text thus creating
the effect of barcode without any value in it.
from Aspose support forum: https://forum.aspose.com/t/creating-2d-bar-code-using-aspose-and-merging-it-in-pdf/7265
if you want to change caption text use this property...
builder.Display2DText = "this is caption text";
By default if it's set to empty string it displays codetext.
Read the properties of bar-code methods in the below link
http://barbecue.sourceforge.net/apidocs/net/sourceforge/barbecue/Barcode.html
Using the setDrawingText(Boolean) default method we remove the text in below bar-code
Example :
Barcode barcode = BarcodeFactory.createCode128(id);
barcode.setDrawingText(false);
BarcodeImageHandler.writePNG(barcode, new FileOutputStream(new File(file Name)));

Java: .gif Creator Needs Tweaking

I currently am creating a program (with Java) that imports images and then creates a .gif with these images.
Most of my images have a transparent background with the alpha set at 0.
My current problem is after I have a series of 8 images converted to one .gif they bleed over each other. In other words the .gif does not repaint over the image before painting the next frame. So for example, if there is an apple fall from the tree, it will look like a red streak until the .gif loops.
I consider myself to be getting pretty savvy with Java but the script I found while searching the archives of the internet is way out of my league. Consider none of my 8 Java books cover IIOMETANODE. And resources on the internet are limited. So I'm not sure what the capabilities of iio are.
Here is the script:
import javax.imageio.*;
import javax.imageio.metadata.*;
import javax.imageio.stream.*;
import java.awt.image.*;
import java.io.*;
import java.util.Iterator;
public class GifCreator {
private ImageWriter gifWriter;
private ImageWriteParam imageWriteParam;
private IIOMetadata imageMetaData;
public GifCreator(){}
/**
* Creates a new GifSequenceWriter
*
* #param output the ImageOutputStream to be written to
* #param imgType one of the imageTypes specified in BufferedImage
* #param frameTime the time between frames in miliseconds
* #param loop wether the gif should loop repeatedly
* #throws IIOException if no gif ImageWriters are found
*
*/
public GifCreator(ImageOutputStream output, int imgType, int frameTime, boolean loop)
{
try {
gifWriter = getWriter();
imageWriteParam = gifWriter.getDefaultWriteParam();
ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(imgType);
imageMetaData = gifWriter.getDefaultImageMetadata(imageTypeSpecifier, imageWriteParam);
String metaFormatName = imageMetaData.getNativeMetadataFormatName();
IIOMetadataNode root = (IIOMetadataNode) imageMetaData.getAsTree(metaFormatName);
IIOMetadataNode graphicsControlExtensionNode = getNode(root, "GraphicControlExtension");
graphicsControlExtensionNode.setAttribute("disposalMethod", "none");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("transparentColorFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("delayTime", Integer.toString(frameTime / 10));
graphicsControlExtensionNode.setAttribute("transparentColorIndex", "0");
IIOMetadataNode appEntensionsNode = getNode(root, "ApplicationExtensions");
IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");
child.setAttribute("applicationID", "NETSCAPE");
child.setAttribute("authenticationCode", "2.0");
int aLoop = loop ? 0 : 1;
child.setUserObject(new byte[]{ 0x1, (byte) (aLoop & 0xFF), (byte) ((aLoop >> 8) & 0xFF)});
appEntensionsNode.appendChild(child);
imageMetaData.setFromTree(metaFormatName, root);
gifWriter.setOutput(output);
gifWriter.prepareWriteSequence(null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void writeToSequence(RenderedImage img) throws IOException
{
gifWriter.writeToSequence(new IIOImage(img, null, imageMetaData), imageWriteParam);
}
/**
* Close this GifSequenceWriter object. This does not close the underlying
* stream, just finishes off the GIF.
*/
public void close() throws IOException
{
gifWriter.endWriteSequence();
}
/**
* Returns the first available GIF ImageWriter using
* ImageIO.getImageWritersBySuffix("gif").
*
* #return a GIF ImageWriter object
* #throws IIOException if no GIF image writers are returned
*/
private static ImageWriter getWriter() throws IIOException
{
Iterator<ImageWriter> iter = ImageIO.getImageWritersBySuffix("gif");
if (!iter.hasNext()) {
throw new IIOException("No GIF Image Writers Exist");
} else {
return iter.next();
}
}
/**
* Returns an existing child node, or creates and returns a new child node (if
* the requested node does not exist).
*
* #param rootNode the <tt>IIOMetadataNode</tt> to search for the child node.
* #param nodeName the name of the child node.
*
* #return the child node, if found or a new node created with the given name.
*/
private static IIOMetadataNode getNode(IIOMetadataNode rootNode, String nodeName)
{
int nNodes = rootNode.getLength();
for (int i = 0; i < nNodes; i++) {
if (rootNode.item(i).getNodeName().compareToIgnoreCase(nodeName) == 0)
return((IIOMetadataNode) rootNode.item(i));
}
IIOMetadataNode node = new IIOMetadataNode(nodeName);
rootNode.appendChild(node);
return(node);
}
public GifCreator(BufferedImage[] imgs, String path)
{
if (imgs.length <= 1)
return;
// Grabs the first BufferedImage from the array.
BufferedImage first = imgs[0];
try {
// Creates a new BufferedOutputStream with the incoming path.
ImageOutputStream output = new FileImageOutputStream(new File(path));
// Creates a gif sequence with the type of the first image, .1 second
// between frames, which loops continuously
GifCreator writer = new GifCreator(output, first.getType(), 100, true);
// write out the first image to our sequence...
writer.writeToSequence((RenderedImage) first);
for (int i = 1; i < imgs.length; i++) {
BufferedImage next = imgs[i];
writer.writeToSequence(next);
}
writer.close();
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Once again I'm trying to change the .gif from bleeding images together. I attempted to create a buffer BufferedImage in between but that was a failure.
Basically, you need to change the disposalMethod...
graphicsControlExtensionNode.setAttribute("disposalMethod", "restoreToBackgroundColor");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute(
"transparentColorFlag",
"TRUE");
Assuming that each image you are adding is a complete image and to an optimised "addition" to the image
Take a look at GIF Animation and Disposal Methods for some more details and if you're really adventurous, the GIF specification and Image :: Java Animated GIFs (with transparant pixel disposal modes) which lists the possible disposal methods, so you can have a play around and see what works...

Re-write the same text into an existing PDF document by using PDFBox

It's a very important question and i am very interested to get any help of you.
I used PDFBox to create a simple PDF document.
That i'am trying to do, is to read the existing document and then re-write the same text into it, and in the same position.
1) Firstly i create a PDF named "Musique.pdf".
2)Read this existing document.
3)extract the text into the document with PDFTextStripper.
3)Find the position of each character in the document (x, y, width, fs, etc. ).
4)create a table that must contain the x and y of each character, for example tabel1 [0]=x1 tabel1[1]=y1 , table1[2]=x2, table1[3]=y2 , etc.
5) Then create a boucle of PDFContentStream to re-write each character in the correct position.
The problem is:
the first line is completely wrote but the problem is with the second line.
"I notice that if we have for example a text formed of 3 lines and if we assume that it contains 225 characters,,so if we get the length of this text, we will put a length equal to 231,,so we can notice that it adds 2 spaces of the end of each line,, but when we search the position of each character, the program does not consider these added spaces"
Please run my below code and tell me how to resolve this problem, please.
My code until now:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package test;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import org.apache.pdfbox.cos.COSInteger;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdfparser.PDFStreamParser;
import org.apache.pdfbox.pdfwriter.ContentStreamWriter;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.PDFTextStripper;
import org.apache.pdfbox.util.TextPosition;
public class Test extends PDFTextStripper{
private static final String src="...";
private static int i;
private static float[] table1;
private static PDPageContentStream content;
private static float jjj;
public Test() throws IOException {
super.setSortByPosition(true);
}
public static void createPdf(String src) throws IOException, COSVisitorException{
//create document named "Musique.pdf"
PDRectangle rec= new PDRectangle(400,400);
PDDocument document= null;
document= new PDDocument();
PDPage page= new PDPage(rec);
document.addPage(page);
PDFont font= PDType1Font.HELVETICA;
PDPageContentStream canvas1= new PDPageContentStream(document,page,true,true);
canvas1.setFont(font, 10);
canvas1.beginText();
canvas1.appendRawCommands("15 385 Td");
canvas1.appendRawCommands("(La musique est très importante dans notre vie moderne. Sans la musique, non)Tj\n");
canvas1.endText();
canvas1.close();
PDPageContentStream canvas2= new PDPageContentStream(document,page,true,true);
canvas2.setFont(font, 11);
canvas2.beginText();
canvas2.appendRawCommands("15 370 Td");
canvas2.appendRawCommands("(Donc il est très necessaire de jouer chaque jours la musique.)Tj\n");
canvas2.endText();
canvas2.close();
document.save("Musique.pdf");
document.close();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException, COSVisitorException {
Test tes= new Test();
tes.createPdf(src);
//read the existing document
PDDocument doc;
doc= PDDocument.load("Musique.pdf");
List pages = doc.getDocumentCatalog().getAllPages();
PDPage page = (PDPage) pages.get(0);
//extract the text existed in the document
PDFTextStripper stripper =new PDFTextStripper();
String texte=stripper.getText(doc);
PDStream contents = page.getContents();
if(contents!=null){
i=1;
table1=new float[texte.length()*2];
table1[0]=(float)15.0;
//the function below call the processTextPosition procedure in order to find the position of each character and put each value in a case of table1
tes.processStream(page, page.findResources(), page.getContents().getStream());
//after execution of processTextPosition, the analysing of code continue to the below code:
int iii=0;
int kkk=0;
//create a boucle of PDPageContentStream in order to re-write completly the text in the document
//when you run this code, you must notice a problem with the second line, so how to resolve this problem ?
PDFont font= PDType1Font.HELVETICA;
while(kkk<table1.length){
content = new PDPageContentStream(doc,page,true,true);
content.setFont(font, 10);
content.beginText();
jjj = 400-table1[kkk+1];
content.appendRawCommands(""+table1[kkk]+" "+jjj+" Td");
content.appendRawCommands("("+texte.charAt(iii)+")"+" Tj\n");
content.endText();
content.close();
iii=iii+1;
kkk=kkk+2;
}
}
//save the modified document
doc.save("Modified-musique.pdf");
doc.close();
}
/**
* #param text The text to be processed
*/
public void processTextPosition(TextPosition text) {
System.out.println("String[" + text.getXDirAdj() + ","
+ text.getYDirAdj() + " fs=" + text.getFontSize() + " xscale="
+ text.getXScale() + " height=" + text.getHeightDir() + " space="
+ text.getWidthOfSpace() + " width="
+ text.getWidthDirAdj() + "]" + text.getCharacter());
if(i>1){
table1[i]=text.getXDirAdj();
System.out.println(table1[i]);
i=i+1;
table1[i]=text.getYDirAdj();
System.out.println(table1[i]);
i=i+1;
}
else{
table1[i]=text.getYDirAdj();
System.out.println(table1[i]);
i=i+1;
}
}
}
Best Regards,
Liszt.
There are shortcomings in your concept and code.
First of all the concept: Your two items numbered 3:
3)extract the text into the document with PDFTextStripper.
3)Find the position of each character in the document (x, y, width, fs, etc. ).
Separating these two steps in my eyes is a bad idea because in general you'll have trouble recognizing the respectively corresponding character from text extraction and glyph from the content.
It will be difficult in general because e.g. which e glyph in the content corresponds to which e character in your text? Counting on the order of appearance in the content stream being identical to the order in the parsed text only works in very simple page contents.
And then there are additional problems imposed by replacements: E.g. text extraction quite likely expands ligatures and for example gives you ff for a ff.
Additionally there is the matter of going back and forth between font encoding and your string encoding which might be quite lossy
Furthermore text extraction likely adds white space characters to the text that are not present in the content. E.g. it can add line breaks where it recognized a jump in the y direction or a space where it recognized a jump in the x direction.
BTW, this most likely is the reason for your observation:
I notice that if we have for example a text formed of 3 lines and if we assume that it contains 225 characters,,so if we get the length of this text, we will put a length equal to 231,,so we can notice that it adds 2 spaces of the end of each line,, but when we search the position of each character, the program does not consider these added spaces.
Furthermore your code makes the PDF size explode
5) Then create a boucle of PDFContentStream to re-write each character in the correct position.
while(kkk<table1.length){
content = new PDPageContentStream(doc,page,true,true);
...
}
I would propose at least only creating a single additional content stream...
What about starting from something like this:
// read the existing document
PDDocument doc;
doc = PDDocument.load(musiqueFileName);
List<?> pages = doc.getDocumentCatalog().getAllPages();
PDPage page = (PDPage) pages.get(0);
PDPageContentStream content = new PDPageContentStream(doc, page, true, true);
TestRewriter rewriter = new TestRewriter(content);
rewriter.processStream(page, page.findResources(), page.getContents().getStream());
content.close();
// save the modified document
doc.save(modifiedMusiqueFileName);
doc.close();
Here TestRewriter is a subclass of PDFTextStripper, too:
public static class TestRewriter extends PDFTextStripper
{
final PDPageContentStream canvas;
public TestRewriter(PDPageContentStream canvas) throws IOException
{
this.canvas = canvas;
}
/**
* #param text
* The text to be processed
*/
public void processTextPosition(TextPosition text)
{
try
{
PDFont font = PDType1Font.HELVETICA;
canvas.setFont(font, 10);
canvas.beginText();
canvas.appendRawCommands("" + (text.getXDirAdj()) + " " + (400 - text.getYDirAdj()) + " Td");
canvas.appendRawCommands("(" + text.getCharacter() + ")" + " Tj\n");
canvas.endText();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
This still is far from perfect but may help you continue...
If you in parallel need to parse the actual text, integrate more of the PDFTextStripper method processTextPosition to combine the functionalities.

Categories