Use an Image as a watermark in iText 7 - java

iText 7 just came out May 2016, and while some of the tutorials have been helpful, some of the more advanced functions have been harder to figure out. This page has an example of how to use text as a watermark (about 90% of the way down the page), but I can't figure out how to use an Image as a watermark, and I really have no idea where to start with the new release. Anyone know how to use an Image as a watermark in iText 7? Any ideas where to start?

I'm not 100% positive this is the right way to do this but I'd say I'm 95% confident.
Using the tutorial for iText 7 that you linked to as a starting guide along with the iText 5 version we can use a "graphics state" to modify the current canvas.
(The code below is C# but you should be able to convert it to Java pretty easily, pretty much just lowercase the first letter of properties and methods. Also, I'm using full namespace paths just so you know where things are at.)
First, create a custom state and set its transparency:
//Create a transparent state
iText.Kernel.Pdf.Extgstate.PdfExtGState tranState = new iText.Kernel.Pdf.Extgstate.PdfExtGState();
tranState.SetFillOpacity(0.5f);
Second, get your image:
//Get your image somehow
iText.IO.Image.ImageData myImageData = ImageDataFactory.Create("D:\\14.jpg", false);
iText.Layout.Element.Image myImage = new iText.Layout.Element.Image(myImageData);
Third (and optional), change your image if needed:
//Position, rotate and scale it as needed
myImage.SetFixedPosition(100, 100);
myImage.SetRotationAngle(45);
myImage.ScaleAbsolute(200, 200);
Fourth, save the pdfCanvas (from the tutorial) state and set a new one:
pdfCanvas.SaveState().SetExtGState(tranState);
Fifth, add your image to the higher level canvas (once again, from the tutorial):
canvas.Add(myImage);
And sixth, reset the pdfCanvas state:
pdfCanvas.RestoreState();
Update by Bruno:
Adding images is explained in Chapter 3 of the "iText 7: Building Blocks" tutorial. In chapter 3 of "iText 7: Jump-Start tutorial", we work with a PdfCanvas and Canvas object. The missing information about how to create and add an image is in the "Building Blocks" tutorial.

Related

Add text to last page of existing PDF with java

I know there are many suggestions how to resolve problems with edition existing PDF, but among all of those, I couldn't find a solution for my problem.
I need to add information about file acceptance ("Document accepted by Tom Smith, 2020-01-01" - possible multiple acceptations) to the last page of the PDF. I need to determine if page is filled or is there enough space for my text.
I wanted to find position (y) of the last element on the last page of the pdf to check it against page size. If the page is full I'm going to add a new page and then add new text.
I have no idea how to resolve this. I tried looking for answers with iText and PDFBOX, but there are no satisfying resolutions.
Raster Image based approach:
Render the last page of the pdf to a bitmap image with any library you are comfortable with (Ghostscript?). 72 dpi should be enough for your purpose.
Then you can use any image processing library like openCV and check rectangular areas starting from the bottom up, if pixel exist. openCV is very fast with the CountNonZero() function.
You can also find any large white zone that is anywhere in the Image, not just at the bottom. This link could be your starting point.
https://answers.opencv.org/question/72939/how-to-find-biggest-white-zone-in-an-scanned-image/

OpenCV - Identifying particular object in image using Java

I'm developing an opencv application in java where I need to detect the different marks on the product.I have attached the input image below
In that image I need to identify the non veg mark.
Since i'm new to it, I need help to know which concepts can be used for it.
I need to identify these marks on the input images
After quite a struggle I was able to come up with a rough solution.
First, I separated the veg and non-veg labels.
&
Now in order to get the perfect fit of the non-veg label over the image I resized it to a particular level:
small = cv2.resize(nveg, (0,0), fx=0.12, fy=0.12)
Now I performed Template matching as I stated in the comments' section. To learn more about this topic VISIT THIS PAGE.
Using it I obtained the 'maximum probable location' of the non-veg label in the image.
res = cv2.matchTemplate(food, small, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
In the following image pay attention to the bright spot in the position of the non-veg mark:
Now using the max_loc variable, I added the tuple values to the size of the resized non-veg label and framed it with a rectangle as in the following:
You can see the black spot on the non-veg mark when I labelled it using max_loc:
Hope this helped. :)

Changing font size in skin

I am writing a game using libgdx, and I borrowed the skin.json (and related files) from a tutorial.
The font being used (default) was scaling in an ugly manner on denser screens, so I generated by own very large font - and in the game itself, I scale it to a reasonable size (basically I use BitmapFont.scale). The font I'm now using is 3 times as large as the previous one.
I changed the reference to which font to use in the skin.json file, and as a result, all my buttons, titles and other things have a massive font being shown.
Is there a way of scaling the font in the .json file? Or anywhere else in the code? Skin doesn't have a setFont() functionality, so I can't create a scaled BitmapFont and assign it)
Libgdx changed this back in April 2015 so that the set answer doesn't work anymore. Took a little bit to find the answer, so I thought I'd leave it here for others since this answer pops up first in Google.
this.getSkin().getFont("default-font").getData().setScale(0.33f,0.33f);
Documentation says that any gets will return a handle to the actual object. So changes will persist.
So I changed the font in skin.json to point to my new font.
Then I used this code
this.getSkin().getFont("default-font").setScale(0.33f, 0.33f);
To scale the 'default-font' (as defined in the skin.json) to the scale I wanted (in my case its 0.33f)
As of 2017 i had to use
skin.getFont("default-font").getData().setScale(0.5f);
for future users.

How do I create an alphablending BufferedImage using J2ME (CDC/PP 1.1)

I have a BufferedImage created using
new BufferedImage(wid,hgt,BufferedImage.TYPE_INT_ARGB);
to which I assemble a wallpaper using multiple other images. It works fine in Jave SE, but when I tried to run the code on a J9 CDC/PP platform I discovered that the Personal Profile BufferedImage has no constructors!
Can anyone point me to how I can construct an alpha-channel supporting image using CDC 1.0 and Personal Profile 1.1?
Edit: For now I have created fallback code which handles NoSuchMethodError (et al.) and then simply creates an image with GraphicsConfiguration.createCompatibleImage(int,int). It might be that that creates an alpha-blending image, but it will be a few weeks before I can specifically test that due to other priorities (testing on handhelds is not my direct responsibility, so it's out of my hands).
If I find a better answer, I will post it as an answer to this; in the meantime, if someone else beats me to it, be assured I will accept your answer if it works, and the answer will be of interest to me for the foreseeable future (I expect to still need an answer in 2-5 years).
The Image class (javax.microedition.lcdui.Image
) contains a method getRGB(...) which parses the Image into an array of RGB+Alpha values for each pixel in the image. Once you have the image in that format, its easy to tweak the alpha values to increase their transparency before you layer the images. This is really the only dynamic way I've seen to edit the transparency of an image in J2ME.
to get the alpha (transparency) value out of the rgba array you have to use bit-shifting like this:
int origAlpha = (rgba[j] >> 24);
and then to change the alpha (transparency) value to something different (without changing the color at that pixel), you can use bitshifting to insert a different transparency level.
int newAlpha = 0x33; // or use whatever 0-255 value you want, with 255=opaque, 0=transparent
rgba[j] = (rgba[j] & 0x00ffffff);
rgba[j] = (rgba[j] | (newAlpha << 24));
Then there is a createImage(...) method in Image that takes a byte-array of image data as a parameter, that can be used to create a new image out of your modified pixel data array.
Also helpful, SonyEricsson's developer website also has a tutorial with sample code called "Fade in and out images in MIDP 2.0" which explains "how to change the alpha value of an image to make it appear blended" which is essentially alpha-blending.

Java 2D Image resize ignoring bicubic/bilinear interpolation rendering hints (OS X + linux)

I'm trying to create thumbnails for uploaded images in a JRuby/Rails app using the Image Voodoo plugin - the problem is the resized thumbnails look like... ass.
It seems that the code to generate the thumbnails is absolutely doing everything correctly to set the interpolation rendering hint to "bicubic", but it isn't honoring them on our dev environment (OS X), or on the production web server (Linux).
I've extracted out the code to generate the thumbnails, rewritten it as a straight Java app (ie kicked off from a main() method) with the interpolation rendering hint explicitly set to "bicubic", and have reproduced the (lack of) bicubic and bilinear resizing.
As expected on both OS X and Linux the thumbanils are ugly and pixelated, but on Windows, it resizes the images nicely with bicubic interpolation used.
Is there any JVM environment setting and/or additional libraries that I'm missing to make it work? I'm doing a lot of banging of head against wall for this one.
I realize this question was asked a while ago, but incase anyone else is still running into this.
The reason the thumbnails look like ass are caused by two things (primarily the first one):
Non-incremental image scaling in Java is very rough, throws a lot of pixel data out and averages the result once regardless of the rendering hint.
Processing a poorly supported BufferedImage type in Java2D (typically GIFs) can result in very poor looking/dithered results.
As it turns out the old AreaAveragingScaleFilter does a decent job of making good looking thumbnails, but it is slow and deprecated by the Java2D team -- unfortunately they didn't replace it with any nice out-of-the-box alternative and left us sort of on our own.
Chris Campbell (from the Java2D team) addressed this a few years ago with the concept of incremental scaling -- instead of going from your starting resolution to the target resolution in one operation, you do it in steps, and the result looks much better.
Given that the code for this is decently large, I wrote all the best-practices up into a library called imgscalr and released it under the Apache 2 license.
The most basic usage looks like this:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 640);
In this use-case the library uses what is called it's "automatic" scaling mode and will fit the resulting image (honoring it's proportions) within a bounding box of 640x640. So if the image is not a square and is a standard 4:3 image, it will resize it to 640x480 -- the argument is just it's largest dimension.
There are a slew of other methods on the Scalr class (all static and easy to use) that allow you to control everything.
For the best looking thumbnails possible, the command would look like this:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY,
150, 100, Scalr.OP_ANTIALIAS);
The Scalr.OP_ANTIALIAS is optional, but a lot of users feel that when you scale down to a small enough thumbnail in Java, some of the transitions between pixel values are a little too discrete and make the image look "sharp", so a lot of users asked for a way to soften the thumbnail a bit.
That is done through a ConvolveOp and if you have never used them before, trying to figure out the right "kernel" to use is... a pain in the ass. That OP_ANTIALIAS constant defined on the class it the best looking anti-aliasing op I found after a week of testing with another user who had deployed imgscalr into their social network in Brazil (used to scale the profile photos). I included it to make everyone's life a bit easier.
Also, ontop of all these examples, you might have noticed when you scale GIFs and some other types of images (BMPs) that sometimes the scaled result looks TERRIBLE compared to the original... that is because of the image being in a poorly supported BufferedImage type and Java2D falling back to using it's software rendering pipeline instead of the hardware accelerated one for better supported image types.
imgscalr will take care of all of that for you and keep the image in the best supported image type possible to avoid that.
Anyway, that is a REALLY long way of saying "You can use imgscalr to do all that for you and not have to worry about anything".
maybe is this a solution for you:
public BufferedImage resizeImage(BufferedImage source, int width, int height)
{
BufferedImage result = new BufferedImage(widht, height, BufferedImage.TYPE_INT_ARGB);
Graphics g = result.getGraphics();
g.drawImage(source, 0, 0, widht, height, null);
g.dispose();
return result;
}
In the end, upgrading to the latest version of ImageVoodoo seemed to improve quality.
Looking through the source code, it looks like they're doing some funky AWT rendering, and then pulling that out. Nasty, but it seems to work.
Still not as good as ImageMagick, but better than it was.
#Riyad, the code for incremental scaling isn't "decently large", it's quite small (As you can see from a post back in 2007, http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html#creating-scaled-instances) having a library that gives other options might be useful, but making a library to use a library is nonsense.

Categories