PDFBox set Signature to Center of the Rectangle - java

Using PDFBox i am try to set signature to center on the box of rectacle, assume the rectacle size is 120x60 and can be customized and image signature can vary, examples 1000*1000 or 640x320 etc. I am try with resize the signature like the box :
// save and restore graphics if the image is too large and needs to be scaled
cs.saveGraphicsState();
cs.transform(Matrix.getScaleInstance(0.85f, 0.85f));
PDImageXObject img = PDImageXObject.createFromFileByExtension(imageFile, doc);
float wpercent = (rect.getWidth() / img.getWidth());
float newHeight = img.getHeight() * wpercent;
cs.drawImage(img, 0,0, rect.getWidth(), newHeight); //Resize image signature fit to rectangle and resize the height by percent to avoid stretch image
cs.restoreGraphicsState();
try to calculate coordinate inside the box
cs.drawImage(img, rect.getWidth()*0.10,rect.getHeight()*0.10, rect.getWidth(), newHeight);
example image got success set on center image size 1880x1000
if the signature just QR size 1000x1000
the QR got cut off
how to fix that ?

Solved refers to Auto resized image
by adding this function to scale image fit to rectangle
public static Dimension getScaledDimension(Dimension imgSize, Dimension boundary) {
int original_width = imgSize.width;
int original_height = imgSize.height;
int bound_width = boundary.width;
int bound_height = boundary.height;
int new_width = original_width;
int new_height = original_height;
// first check if we need to scale width
if (original_width > bound_width) {
//scale width to fit
new_width = bound_width;
//scale height to maintain aspect ratio
new_height = (new_width * original_height) / original_width;
}
// then check if we need to scale even with the new height
if (new_height > bound_height) {
//scale height to fit instead
new_height = bound_height;
//scale width to maintain aspect ratio
new_width = (new_height * original_width) / original_height;
}
return new Dimension(new_width, new_height);
}
then add to this function
Dimension scaledDim = getScaledDimension(new Dimension(img.getWidth(), img.getHeight()), new Dimension((int)rect.getWidth(), (int)rect.getHeight()));
int x = ((int) rect.getWidth() - scaledDim.width) / 2;
int y = ((int) rect.getHeight() - scaledDim.height) / 2;
cs.drawImage(img, x, y, scaledDim.width, scaledDim.height);

Related

Resize Java BufferedImage keeping aspect ratio and fill with background

I'm working with Java to store and modify .jpg images, (not Android or Swing). I want to transform an image with a new dimension keeping the aspect ratio and filling the background with white color if the new dimension is not proportional to the original image.
BufferedImage image = /*Here i read from disk and load the image */;
image = resizeImage(image, newWidth, newHeight);
ImageIO.write(image, extension, new File(filename + "_" + page + "." + extension));
The function I'm trying to implement is resizeImage: in the example resizes the image but it doesn't keep the aspect ratio.
private static BufferedImage resizeImage(BufferedImage originalImage, int width, int height) {
BufferedImage resizedImage = new BufferedImage(width, height, originalImage.getType());
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
I think a picture will be more illustrative of what I'm asking for:
If the original image is 200x200 and is asked to resize to 400x300 the result should be a picture with white margin and the original picture resized inside. In this example should be 300x300.
The problem is not how to resize, it's how to fill the remaining image with white and the original resized image on the center of it.
This code worked for me:
private static BufferedImage resizeImage(BufferedImage originalImage, int newWidth, int newHeight) {
BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, originalImage.getType());
Graphics2D graphics = resizedImage.createGraphics();
graphics.setColor(Color.WHITE);
// fill the entire picture with white
graphics.fillRect(0, 0, newWidth, newHeight);
int maxWidth = 0;
int maxHeight = 0;
// go along the width and height in increments of 1 until one value is equal to the specified resize value
while (maxWidth <= newWidth && maxHeight <= newHeight)
{
++maxWidth;
++maxHeight;
}
// calculate the x value with which the original image is centred
int centerX = (resizedImage.getWidth() - maxWidth) / 2;
// calculate the y value with which the original image is centred
int centerY = (resizedImage.getHeight() - maxHeight) / 2;
// draw the original image
graphics.drawImage(originalImage, centerX, centerY, maxWidth, maxHeight, null);
graphics.dispose();
return resizedImage;
}
Before:
After:

How to create an image file with fixed size in Android?

I built a simple app that you can pick a photo of yourself, select a border for it and then save it as image. The way I did this is adding 2 ImageViews on top of each other in a parent view. Then converting this parent view to image and save. However with this way, the resulting image size depends on the device screen size. If the device screen is small, a small final image is generated.
What I want is creating an image file with a size of 500x800 pixels at all times regardless of device. What is the correct way to do this?
The preview on the screen could be small, but when I click save button I need it to be exactly 500x800.
First, convert your image to bitmap by :
Bitmap bitmapImage= BitmapFactory.decodeResource(getResources(), R.drawable.large_icon);
Or, if you have Uri of image then use this to convert it to bitmap:
Bitmap bitmap = BitmapFactory.decodeFile(imageUri.getPath());
Both of this will give you a bitmap of your image.
Now to resize your image use this code:
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, imageWidth, imageHeight, true);
Then convert it into File.
To Add to Jason Answer, we found the best way to scale the image, is to use this to scale it up or down.
public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) {
int sourceWidth = source.getWidth();
int sourceHeight = source.getHeight();
// Compute the scaling factors to fit the new height and width, respectively.
// To cover the final image, the final scaling will be the bigger
// of these two.
float xScale = (float) newWidth / sourceWidth;
float yScale = (float) newHeight / sourceHeight;
float scale = Math.max(xScale, yScale);
// Now get the size of the source bitmap when scaled
float scaledWidth = scale * sourceWidth;
float scaledHeight = scale * sourceHeight;
// Let's find out the upper left coordinates if the scaled bitmap
// should be centered in the new size give by the parameters
float left = (newWidth - scaledWidth) / 2;
float top = (newHeight - scaledHeight) / 2;
// The target rectangle for the new, scaled version of the source bitmap will now
// be
RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);
// Finally, we create a new bitmap of the specified size and draw our new,
// scaled bitmap onto it.
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
Canvas canvas = new Canvas(dest);
canvas.drawBitmap(source, null, targetRect, null);
return dest;
}
Please try to below code to save bitmap image as custom height & width, Below is a snippet of code that will allow you to resize a Bitmap.
public Bitmap getResizeBitmap(Bitmap bmp, int newHeight, int newWidth) {
int width = bmp.getWidth();
int height = bmp.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// RECREATE THE NEW BITMAP
Bitmap resizeBitmap = Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, false);
return resizeBitmap;
}

How to use scale in java 2DG

I am drawing some 2Dgraphics to JPanel.
I don't understant how to use scale if i change JPanelsize?
I have an image, which is composed of multiple lines and circles.
Is possible to compute a transformation and that multiply the values that miscalculation? How? Can you give me an example?
A neat way to do it (but not the best) is to have a final variable for the Width and Height, and everything is calculated based on those variables. then you could have a scale variable that is the size of the (JPanel / final Variable) and when you do g.draw() you can set the width to width * wScale, and the height to height * hScale. here is an example
public final WIDTH = 1080;
public final HEIGHT = WIDTH * 16 / 9;
private float wScale = 1;
private float hScale = 1;
public static void mainLoop()
{
wScale = jpanelWidth / (WIDTH * 1.0);
hScale = jpanelHeight / (HEIGHT * 1.0);
//makes the image to draw using the final width and height for calculations
someclass.makeImage(WIDTH, HEIGHT);
//gets an image that has the dimentions of WIDTH and HEIGHT
someimage = someclass.getImage();
//draws the image using its width and scales it to the actual size by multiplying it by the scaler
//the two zeros are at position (0, 0), and null is just the observer.
somegraphics.draw(someimage, 0, 0, (WIDTH * wScale), (HEIGHT * hScale), null);
}
if you need more information or have questions, you can ask for clarification, or contact me personally.

Scaled image blurry in PDFBox

I'm trying to scaling an image with size = 2496 x 3512 into a PDF document. I'm using PDFBox to generate it but the scaled image ends up blurred.
Here are some snippets:
PDF Page size (A4) returned by page.findMediaBox().createDimension(): java.awt.Dimension[width=612,height=792]
Then I calculate the scaled dimension based on the Page size vs. Image size which returns: java.awt.Dimension[width=562,height=792]
I use the code below in order to calculate the scaled dimension:
public static Dimension getScaledDimension(Dimension imgSize, Dimension boundary) {
int original_width = imgSize.width;
int original_height = imgSize.height;
int bound_width = boundary.width;
int bound_height = boundary.height;
int new_width = original_width;
int new_height = original_height;
// first check if we need to scale width
if (original_width > bound_width) {
//scale width to fit
new_width = bound_width;
//scale height to maintain aspect ratio
new_height = (new_width * original_height) / original_width;
}
// then check if we need to scale even with the new height
if (new_height > bound_height) {
//scale height to fit instead
new_height = bound_height;
//scale width to maintain aspect ratio
new_width = (new_height * original_width) / original_height;
}
return new Dimension(new_width, new_height);
}
And to actually perform the image scaling I'm using Image Scalr API:
BufferedImage newImg = Scalr.resize(img, Scalr.Method.ULTRA_QUALITY, Scalr.Mode.FIT_EXACT,
scaledWidth, scaledHeight, Scalr.OP_ANTIALIAS);
My question is what am I doing wrong? A big image shouldn't be blurred when scaled to a smaller size. Is this something related to the PDF page resolution/size?
Thank you,
Gyo
Ok, I found a way to add images without losing the quality.
Actually to make the image not be blurred I let PDFBox to resize the image by giving it the desired size. Like the code below:
PDXObjectImage ximage = new PDJpeg(doc, new FileInputStream(new File("/usr/gyo/my_large_image.jpg")), 1.0f);
PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, false);
Dimension scaledDim = getScaledDimension(new Dimension(ximage.getWidth(), ximage.getHeight()), page.getMediaBox().createDimension());
contentStream.drawXObject(ximage, 1, 1, scaledDim.width, scaledDim.height);
contentStream.close();
Thank you,
Gyo

Rotate an Image in memory

I keep in memory a list of java.Awt Images and have the need to rotate them. I've read some solutions but they deal with changing the way the image is shown, not really rotating the image itself.
I need to rotate an image itself, not to draw in in a rotated way. How can this be attained?
The following code will rotate an image by an arbitrary angle in degrees.
Positive values for degrees will rotate the image clockwise, negative values counterclockwise.
The resulting image will be adjusted in size, so that the rotated image fits exactly into it.
I have tested it with jpg and png image files as input.
public static BufferedImage rotateImage(BufferedImage src, double degrees) {
double radians = Math.toRadians(degrees);
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
/*
* Calculate new image dimensions
*/
double sin = Math.abs(Math.sin(radians));
double cos = Math.abs(Math.cos(radians));
int newWidth = (int) Math.floor(srcWidth * cos + srcHeight * sin);
int newHeight = (int) Math.floor(srcHeight * cos + srcWidth * sin);
/*
* Create new image and rotate it
*/
BufferedImage result = new BufferedImage(newWidth, newHeight,
src.getType());
Graphics2D g = result.createGraphics();
g.translate((newWidth - srcWidth) / 2, (newHeight - srcHeight) / 2);
g.rotate(radians, srcWidth / 2, srcHeight / 2);
g.drawRenderedImage(src, null);
return result;
}

Categories

Resources