I want to add some text to image. and I'm using imgscalr.
I'm looking for some examples or tutorials.
in case you know some better java based image library, please do let me know.
thanks!
Hmm, interesting suggestion. I never anticipated that people would want to render text to their images using imgscalr -- but with the popularity of meme images, maybe I should have thought of that :)
Since imgscalr is processing and returning standard BufferedImages in Java, you are free to use all the existing Java2D rendering libs to paint text to the image.
To do that you want to call BufferedImage.getGraphics() on the image you are processing, cast that to a Graphics2D object like so:
Graphics2D g2d = (Graphics2D)myImage.getGraphics();
Then you can use the standard Graphics2D font rendering methods to "draw" text onto your image. For example, something like:
g2d.drawString("I haz a hat!", 50, 50);
Also you can change how the font looks by using the Graphics.setFont(...) call.
In the future I may add convenience methods to imgscalr to do this for you now that you have given me this idea ;)
Related
I have a renderer I've been using to draw a complex set of stuff onto a Graphics2D context, including rotated text using transforms and Graphics2D.drawString().
Now I want to see what it would take to draw stylized text, and it looks like it would be a quagmire, except that the JLabel class handles this nicely by itself if you use HTML e.g.:
<html>a<sup>2</sup> + b<sup>2</sup> = c<sup>2</sup></html>
Which of the following is a simpler approach, and how do I get started down that path?
Use a JLabel to render text onto my Graphics2D context, emulating the way a JTable uses renderers by having a component like JLabel do the rendering. (which I tried doing, but I can't seem to get it to work; not sure what method to call -- paint() or paintComponents()? -- and not sure if it works with rotated graphics transforms)
Parse HTML or some other simplified formatting language (like the subset of TeX used by MATLAB for graphs) and continue using drawString(), but handle the formatting myself.
In my opinion your best option is doing #1, using your JLabel as a renderer. I did actually confirm a while back that you can get standard swing components to rotate (display it pretty easy - events are trickier)
I've used Greg Hinkle's VerticalLabelUI to good effect.
I created a subclass of JLabel called VerticalLabel, and it automatically picks up the VerticalLabelUI in the same package. Even works with JFormDesigner GUI builder that way!
Using this example with your HTML seems to work:
You can try this http://java-sl.com/vertical.html
Is it possible to use Graphics2D in a servlet?
And if I have a Graphics2D object, is it possible for me to convert it to a .jpg image and display it in a JSP page?
In my opinion yes, Read the link for better understanding.
JFreeChart has a good example of doing this. To accommodate older versions, it provides a org.jfree.chart.encoders.SunJPEGEncoderAdapter. The encode() method shows how to use ImageIO for either byte array or stream.
I'm a reasonably experienced Java programmer but relatively new to Java2D. I'm trying to scale an image but I'm getting poor quality results. The image is a preview of a panel so contains things like text and textfields. I'll always be scaling down, never up.
Currently I'm using the following code:-
g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null);
Where panelImage is the full sized preview (BufferedImage) and scaledWidth and scaledHeight are the respective target dimensions. I seem to lose a lot of detail in the text and edges of things like textfields etc.
Is there a better call I should be using to scale the image?
Thanks,
John
A suggestion I can make is to first resize the image onto a separate BufferedImage. The reason being, a Graphics2D object of the BufferedImage can be obtained in order to produce a better quality scaled image.
Graphics2D can accept "rendering hints" which instruct the way image processing should be performed by the Graphics2D object. The setRenderingHint method is one of the methods which can be used to set those rendering hints. The rendering hints from the RenderingHints class can be used.
Then, using that Graphics2D object, an image can be drawn to the BufferedImage using the rendering hints specified earlier.
A rough (untested) code would work as the following:
BufferedImage scaledImage = new BufferedImage(
scaledWidth,
scaledHeight,
BufferedImage.TYPE_INT_RGB
);
Graphics2D g = scaledImage.createGraphics();
g.setRenderingHints(
RenderingHints.Key.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC
);
g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
Other rendering hints of interest may include:
KEY_ANTIALIASING
KEY_RENDERING
The Controlling Rendering Quality section of The Java Tutorials also has more information on how to control the rendering quality of Graphics2D objects.
And for a very good source of information on dealing with graphical interfaces in general, Filthy Rich Clients by Chet Haase and Romain Guy is highly recommended. There is one section of the book that deals with the issue of scaling images, which seems quite relevant.
May be you should call:
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
and
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Coobird is right that you need to incrementally down-scale (preferably using BICUBIC) to get a good-looking result for a small enough thumbnail. Image.getScaledInstance used to do this with the AREA_AVERAGED approach, but it is much slower than the incremental downscale that was original proposed by Chris Campbell in his "Perils of Image.getScaledInstance()" article.
Please excuse the self-promotion here, but I rolled a handful of "native Java best practices" when it comes to image scaling into a library called imgscalr.
It's available under an Apache 2 license and source is all on GitHub; the goal of the library was to make image-scaling in native Java dead-easy (1 class, 5 static methods) and ensure the best looking result (which is what you originally wanted), the fastest result (great when scaling among large images) or a balance between the two and let the library decide which one to use.
I just wanted a lib that could "Resize my image and get out of my way" and after reading all these posts for a few days as I addressed the pain point (my own as well) just was circling back and sharing the work for anyone else it may help.
Coobird has the correct idea. I would also try RenderingHints.VALUE_INTERPOLATION_BILINEAR interpolation and see if it's nicer looking. Bicubic works better when upscaling, though. For the best results when downscaling, one should downscale in several steps. First halve the resolution, then halve again, etc. until you get near the desired resolution (i.e. you cannot halve or the image will get too small). Final step is to scale down to the desired resolution.
For example, let's say your input image is 800x600 and you want downscale to 160x120:
Downscale 50%. --> 400x300
Downscale 50%. --> 200x150
Downscale to 160x120.
I would like to export the image in my JPanel to a vector graphics file so it can be edited and printed at a higher-than-screen resolution. Essentially I want its paint() function to be called with a destination Graphics that saves the drawing commands into a vector graphic file.
What is a good, simple way to do this? What libraries are recommended? Which vector format would be best, and why?
Have a look at The Java EPS Graphics2D package.
Many Java programs use Graphics2D to draw stuff on the screen, and while it is easy to save the output as a png or jpeg file, it is a little harder to export it as an EPS for including in a document or paper.
This package makes the whole process extremely easy, because you can use the EpsGraphics2D object as if it's a Graphics2D object. The only difference is that all of the implemented methods create EPS output, which means the diagrams you draw can be resized without leading to any of the jagged edges you may see when resizing pixel-based images, such as JEPG and PNG files.
Apache Batik will let you paint to a specialised implementation of a Graphics2D object and then export as an scalable vector graphics (.svg) file. You can then view/process/print it using an SVG-enabled browser (Firefox will handle it nativly, ISTR, IE and others can use plugins).
See the SVGGraphics2D object (process documented here)
The Java EPS mentioned by Pierre looks good, but if it isn't you might also like to look at FreeHEP Vector Graphics. Written to allow Java reuse in the High Energy Physics field it includes a vector graphics package, done through an implementation of Graphics2D. We've used it to export EPS very successfull for a number of years.
I can recommend the VectorGraphics2D library (LGPL). Although it does not support all the features of Graphics2D, I used it successfully for my project. It provides implementations of java.awt.Graphics2D for various vector file formats. It simply exports all paint operations to EPS, SVG, or PDF files.
Additional libraries for people with the same requirement:
for SVG, JFreeSVG at http://www.jfree.org/jfreesvg/
for PDF, OrsonPDF at http://object-refinery.com/orsonpdf/index.html
Both of these GPLv3 and well tested via extensive usage in JFreeChart and Orson Charts.
FreeHEP seems to work quite well although it does not appear to be maintained anymore and its bug and forum pages are gone. With just a handful of lines you get a popup dialog that can save any component to a variety of scalable and regular image formats. We have some challenging images, using alpha channel, rotated text, areas bounded by curves, and they saved perfectly, much better with with VectorGraphics2D.
The only problem I've seen so far is in jpeg save, which comes out black for all my images. This isn't very important for us given that png works, plus all the vector modes, but I'm sure it would be an issue for some.
I had to add exactly this much code to save in all these modes:
public static void showImage(Component comp)
{
try
{
ExportDialog export = new ExportDialog();
export.showExportDialog( null, "Export view as ...", comp, "export" );
System.err.println("Image save complete");
}
catch(Exception e)
{
e.printStackTrace();
}
}
There are a bunch of library jars that must be added as well.
this is basically not possible directly, as the low level java api works in terms of raster (pixels) and is never stored in vector format.
(Check the API of java.awt.Graphics to see what I mean).
there are some general purpose program that convert raster to vector formats, this is one I found on a quick search:
http://autotrace.sourceforge.net/index.html
so, using such a program you can divide your problem into two smaller problems:
convert your JPanel into a bitmap or file (http://www.jguru.com/faq/view.jsp?EID=242020)
run autotrace on the file.
Alex explained what I'm looking for much better than I have:
You want an existing program that
allows you to draw a picture, captures
what you do as you draw, and writes
each action as a Java command. When
you click the "Drawl Oval" tool and
click at 0,0 and then at 50,50, it
would generate the line
g.drawOval(0,0,50,50).
If anybody knows of a program such as this, let me know. Thanks.
Original question:
I've been working with Java and custom drawing using the java.awt.Graphics library lately, but find it is taking too much time to write manually. Is there any simple graphics editor (like mspaint) which generates source code?
Example:
Drawing this:
Would generate:
public void update(Graphics g) {
g.translate(0, 0);
g.drawOval(0, 0, 50, 50);
}
Thanks.
If they are vectors, you could use an SVG Editor (eg, Inkscape) along with Kirill's SVG to Java2D Transcoder to simplify this. It isn't perfect, but Kirill is very responsive in responding to requests for enhancement.
It's unclear what you are asking. Two guesses:
You want an existing program that allows you to draw a picture, captures what you do as you draw, and writes each action as a Java command. When you click the "Drawl Oval" tool and click at 0,0 and then at 50,50, it would generate the line g.drawOval(0,0,50,50).
I do not know of any such tool. But the above might help you reword your question so that others can share their knowledge.
You want a program that takes an existing bitmap and converts it into a series of commands that will replicate the bitmap. Other than simply outputting pixels, such a tool is nearly impossible to write; attempting to decompose an arbitrary picture into simple drawing commands is very hard.
In this case, I would recommend simply importing the bitmap as a JPG, PNG, whatever, and using drawImage() instead of using Graphics calls.
While not what you were looking for, I should mention that XPM (X Pixmap) format is basically a subset of C programming language. XPM2 simplified it more by removing the trappings of C syntax. XPM3 brought them back again.
In a sense XPM image converters are source code generators and translators.
You are looking for something similar to output Java AWT, but for many real images or photographs it would be complicated to do analysis on the image to find oval,etc and create the code for drawing them with lines and shapes (well unless the image had filters applied to simplify it, or was an SVG as someone pointed out). It would probably have to convert to a bitmap of some form and keep it in an array in the generated Java source.