I'm trying to perform a signing and want to generate the same multiple appearances. Is there a way to achieve a custom appearance as we can generate in normal cases?
PdfSignatureFormField sigField = (PdfSignatureFormField) acroForm.getField(fieldName);
sigField.addKid(
createSubField(pdfPage, 40, 700, 100, 40, "sig1", signatureDictionary, document));
sigField.addKid(
createSubField(pdfPage, 400, 600, 100, 40, "sig2", signatureDictionary, document));
The following is the method which is generating subfields.
public static PdfFormField createSubField(PdfPage page, float x, float y, float width,
float height, String name, PdfDictionary signatureDictionary, PdfDocument pdfDocument) {
PdfFormXObject appearance = new PdfFormXObject(new Rectangle(width, height));
PdfCanvas pdfCanvas = new PdfCanvas(appearance, pdfDocument);
try (Canvas canvas = new Canvas(pdfCanvas, new Rectangle(width, height))) {
canvas.showTextAligned(name, 2, 2, TextAlignment.LEFT);
}
PdfDictionary ap = new PdfDictionary();
ap.put(PdfName.N, appearance.getPdfObject());
PdfWidgetAnnotation widget = new PdfWidgetAnnotation(new Rectangle(x, y, width, height));
widget.setFlags(PdfAnnotation.PRINT | PdfAnnotation.LOCKED);
widget.setPage(page);
widget.put(PdfName.AP, ap);
PdfSignatureFormField sigField = PdfFormField.createSignature(pdfDocument);
sigField.setFieldName(name);
sigField.addKid(widget);
sigField.put(PdfName.V, signatureDictionary);
page.addAnnotation(widget);
return sigField;
}
Related
I'm trying to draw curves with gradient stroke color not fill color using JAVA PDFbox, anyone can help me with how to do that?
For filling shapes I'm using:
contentStream.clip();
contentStream.shadingFill(PdfUtils.createGradientColor(gradientFactors));
public static PDShadingType2 createGradientColor(GradientFactors gradientFactors) throws IOException {
Color startColor = gradientFactors.getStartColor().getColor();
Color endColor = gradientFactors.getEndColor().getColor();
COSDictionary fdict = new COSDictionary();
fdict.setInt(COSName.FUNCTION_TYPE, 2);
COSArray domain = new COSArray();
domain.add(COSInteger.get(0));
domain.add(COSInteger.get(1));
COSArray c0 = new COSArray();
c0.add(new COSFloat(startColor.getRed() / 255f));
c0.add(new COSFloat(startColor.getGreen() / 255f));
c0.add(new COSFloat(startColor.getBlue() / 255f));
COSArray c1 = new COSArray();
c1.add(new COSFloat(endColor.getRed() / 255f));
c1.add(new COSFloat(endColor.getGreen() / 255f));
c1.add(new COSFloat(endColor.getBlue() / 255f));
fdict.setItem(COSName.DOMAIN, domain);
fdict.setItem(COSName.C0, c0);
fdict.setItem(COSName.C1, c1);
fdict.setInt(COSName.N, 1);
PDFunctionType2 func = new PDFunctionType2(fdict);
PDShadingType2 axialShading = new PDShadingType2(new COSDictionary());
axialShading.setColorSpace(PDDeviceRGB.INSTANCE);
axialShading.setShadingType(PDShading.SHADING_TYPE2);
COSArray coords1 = new COSArray();
coords1.add(new COSFloat(gradientFactors.getX1()));
coords1.add(new COSFloat(gradientFactors.getY1()));
coords1.add(new COSFloat(gradientFactors.getX2()));
coords1.add(new COSFloat(gradientFactors.getY2()));
axialShading.setCoords(coords1);
axialShading.setFunction(func);
return axialShading;
}
Could anyone please help me with this?
As already indicated by Tilman, you create a PDColor from your shading:
PDShadingType2 shading = createGradientColor(...);
PDShadingPattern pattern = new PDShadingPattern();
pattern.setShading(shading);
COSName name = page.getResources().add(pattern);
PDColor color = new PDColor(name, new PDPattern(null));
Then you draw with that color, e.g.:
try ( PDPageContentStream canvas = new PDPageContentStream(document, page)) {
canvas.setStrokingColor(color);
canvas.setLineWidth(5);
canvas.moveTo(0, 0);
canvas.lineTo(500, 500);
canvas.curveTo2(500, 250, 250, 250);
canvas.curveTo1(0, 250, 0, 0);
canvas.stroke();
}
Assuming that gradient goes from red to green from 0,0 to 500,500, the result looks like this:
(DrawGradient test testDrawWithGradientColor)
This question was answered many time but I still can't apply it to my situation.
I want to rotate image on 90 degrees clockwise.
I'm currently having following code:
private void writeImage(BufferedImage sourceImage, String Path) throws IOException {
BufferedImage result;
Graphics2D g;
AffineTransform at = new AffineTransform();
//Do some magic right here to correctly rotate the image itself
if (sourceImage.getWidth() > sourceImage.getHeight()) {
//Do some stuff that somehow works:
result = new BufferedImage(sourceImage.getHeight(null), sourceImage.getWidth(null), BufferedImage.TYPE_INT_RGB);
g = result.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// Anti-alias!
g.translate((result.getHeight() - result.getWidth()) / 2, (result.getHeight() - result.getWidth()) / 2);
g.rotate(Math.toRadians(90f), sourceImage.getHeight() / 2, sourceImage.getWidth() / 2);//simple try
} else {
result = new BufferedImage(sourceImage.getWidth(null), sourceImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
g = result.createGraphics();
}
//result = new BufferedImage(sourceImage.getWidth(null), sourceImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
//g = result.createGraphics();
/*
if (result.getWidth() > result.getHeight()) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// Anti-alias!
//g.translate(170, 0);
g.rotate(Math.toRadians(90));
//g.translate((result.getHeight() - result.getWidth()) / 4, (result.getHeight() - result.getWidth()) / 4);
//g.rotate(Math.PI / 2, result.getHeight() / 2, result.getWidth() / 2);
//g.drawImage(sourceImage, 0, 0, result.getHeight(), result.getWidth(), Color.WHITE, null);
//AffineTransformOp op = new AffineTransformOp(rotateClockwise90(result), AffineTransformOp.TYPE_BILINEAR);
//op.filter(sourceImage, result);
int tempHeight = result.getHeight();
int tempWidth = result.getWidth();
BufferedImage rotated = resize(result, tempHeight, tempWidth);
//result = rotated;
result = resize(result, result.getHeight(), result.getWidth());
}*/
g.drawImage(sourceImage, 0, 0, result.getWidth(), result.getHeight(), Color.WHITE, null);
//g.drawImage(sourceImage, at, null);
g.dispose();
//BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
//g = bufferedImage.createGraphics();
//Color.WHITE estes the background to white. You can use any other color
//g.drawImage(image, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), Color.WHITE, null);
File output = new File(Path);
OutputStream out = new FileOutputStream(output);
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(out);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
if (param.canWriteCompressed()) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(IMAGE_QUALITY);
}
writer.write(null, new IIOImage(result, null, null), param);
out.close();
ios.close();
writer.dispose();
}
Current Result
The source image and 'BufferedImage sourceImage' looks like this:
Source Image
And what I expect to see is this:
Expected
Thanks!
Here is a more general solution that will allow rotation of any specified degrees:
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
public class Rotation
{
public static BufferedImage rotateImage(BufferedImage original, double theta)
{
// Determine the size of the rotated image
double cos = Math.abs(Math.cos(theta));
double sin = Math.abs(Math.sin(theta));
double width = original.getWidth();
double height = original.getHeight();
int w = (int)(width * cos + height * sin);
int h = (int)(width * sin + height * cos);
// Create empty image and fill in background
BufferedImage rotated = new BufferedImage(w, h, original.getType());
Graphics2D g2 = rotated.createGraphics();
g2.setPaint(UIManager.getColor("Panel.background"));
g2.fillRect(0, 0, w, h);
// Rotate the image
double x = w/2;
double y = h/2;
AffineTransform at = AffineTransform.getRotateInstance(theta, x, y);
x = (w - width)/2;
y = (h - height)/2;
at.translate(x, y);
g2.drawRenderedImage(original, at);
g2.dispose();
return rotated;
}
private static void createAndShowGUI()
{
BufferedImage bi;
try
{
String path = "mong.jpg";
ClassLoader cl = Rotation.class.getClassLoader();
bi = ImageIO.read( cl.getResourceAsStream(path) );
}
catch (Exception e) { return; }
JLabel label = new JLabel( new ImageIcon( bi ) );
label.setBorder( new LineBorder(Color.RED) );
label.setHorizontalAlignment(JLabel.CENTER);
JPanel wrapper = new JPanel();
wrapper.add( label );
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 360, 0);
slider.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
int value = slider.getValue();
BufferedImage rotated = Rotation.rotateImage(bi, Math.toRadians(value) );
label.setIcon( new ImageIcon(rotated) );
}
});
JFrame frame = new JFrame("Rotation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(wrapper, BorderLayout.CENTER);
frame.add(slider, BorderLayout.PAGE_END);
frame.setSize(600, 600);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
}
}
Try
g.drawImage(sourceImage, 0, 0, sourceImage.getWidth(), sourceImage.getHeight(), Color.WHITE, null);
I want to create a String which displays the time in the format: 10h 30min, but the units (h and min) should have a smaller font than the numbers. When using a JLabel, I get this work with a html formatted string with span attributes.
Now I want to add such a String to a custom object and write it with the drawAlignedString method. But, here the html passing does not working. The custom object than shows my code and not the formatted String.
Is there a way to get this working or any other solution for drawing Strings with diffrent Substrings?
This is what I've tried:
String time = String.format(
"<html>%d<span style=\"font-family:Arial Unicode MS;font-size:12px;\">h </span> %d<span "
+ "style=\"font-family:Arial Unicode MS;font-size:12px;\">min</span></html>",
absSeconds / 3600, (absSeconds % 3600) / 60);
g2.setFont(this.centerTextFont);
g2.setPaint(this.centerTextColor);
TextUtilities.drawAlignedString(time, g2, (float) area.getCenterX(), (float) area.getCenterY(),
TextAnchor.CENTER);
Once the label is configured, pass the Graphics to the paint method of the label.
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class LabelRenderTest {
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
String title = "<html><body style='width: 200px; padding: 5px;'>"
+ "<h1>Do U C Me?</h1>"
+ "Here is a long string that will wrap. "
+ "The effect we want is a multi-line label.";
JFrame f = new JFrame("Label Render Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage image = new BufferedImage(
400,
300,
BufferedImage.TYPE_INT_RGB);
Graphics2D imageGraphics = image.createGraphics();
GradientPaint gp = new GradientPaint(
20f,
20f,
Color.red,
380f,
280f,
Color.orange);
imageGraphics.setPaint(gp);
imageGraphics.fillRect(0, 0, 400, 300);
JLabel textLabel = new JLabel(title);
textLabel.setSize(textLabel.getPreferredSize());
Dimension d = textLabel.getPreferredSize();
BufferedImage bi = new BufferedImage(
d.width,
d.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
g.setColor(new Color(255, 255, 255, 128));
g.fillRoundRect(
0,
0,
bi.getWidth(f),
bi.getHeight(f),
15,
10);
g.setColor(Color.black);
textLabel.paint(g);
Graphics g2 = image.getGraphics();
g2.drawImage(bi, 20, 20, f);
ImageIcon ii = new ImageIcon(image);
JLabel imageLabel = new JLabel(ii);
f.getContentPane().add(imageLabel);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
});
}
}
I'm trying to create a section of a page in EPS and then have that portion of EPS be imported into my PS document at a specific location using Tools for Adobe Postscript: https://xmlgraphics.apache.org/commons/postscript.html
So far I've got a basic generation for the postscript file, and I want to add EPS to it. Here's a pseudo version of what I'd like to do.
OutputStream out = new java.io.FileOutputStream(outputFile);
out = new java.io.BufferedOutputStream(out);
try {
//Instantiate the PSDocumentGraphics2D instance
PSDocumentGraphics2D g2d = new PSDocumentGraphics2D(false);
g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
EPSDocumentGraphics2D eg2d = new EPSDocumentGraphics2D(false);
eg2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
//Set up the document size
g2d.setupDocument(out, pageWidthPT, pageHeightPT);
eg2d.setupDocument(out, 400, 200); //400pt x 200pt
g2d.setFont(new Font(font, Font.PLAIN, fontSize));
//Paint a bounding box
eg2d.drawRect(0, 0, 400, 200);
//A few rectangles rotated and with different color
Graphics2D copy = (Graphics2D)eg2d.create();
int c = 12;
for (int i = 0; i < c; i++) {
float f = ((i + 1) / (float)c);
Color col = new Color(0.0f, 1 - f, 0.0f);
copy.setColor(col);
copy.fillRect(70, 90, 50, 50);
copy.rotate(-2 * Math.PI / (double)c, 70, 90);
}
copy.dispose();
//Some text
eg2d.rotate(-0.25);
eg2d.setColor(Color.RED);
eg2d.setFont(new Font("sans-serif", Font.PLAIN, 36));
eg2d.drawString("Hello world!", 140, 140);
eg2d.setColor(Color.RED.darker());
//Cleanup
eg2d.finish();
g2d.insertEPS(eg2d, 0,0); // something like this?
g2d.nextPage();
g2d.drawString("Hello World!", 10, 20);
g2d.finish();//Cleanup
} finally {
IOUtils.closeQuietly(out);
}
If you know how to accomplish this goal I would appreciate some enlightenment. Thanks.
I am dragging and dropping the jTable cell from one jTable to another jTable.For Now it is showing me default drag drop icon.
I am using TransferHandler class to implement this.
I Override getDragImage(image) to put my customize image But it is not working.
This way i implemented my code Implementation
I tried this code into this method.
File newFile = new File("./dragImage.jpeg");
Font font = new Font("Tahoma", Font.PLAIN, 11);
FontRenderContext frc = new FontRenderContext(null, true, true);
Rectangle2D bounds = font.getStringBounds(l_value, frc);
int w = (int) bounds.getWidth();
int h = (int) bounds.getHeight();
BufferedImage image = new BufferedImage(10,10, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, 10, 10);
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(l_value, (float) bounds.getX(), (float) -bounds.getY());
g.dispose();
return image;
This code is working in my main method but here in this function it is not working.