There are about 100 jpeg & png color images used in our JavaFX-built desktop app which, when the window is resized, become stretched and blurry so I'd like to have all the graphics remade in a format that will allow them to be dynamically resized without losing quality. What image format or procedure should be used to do this?
Currently, each image is simply in an ImageView and resized as follows, but I'm open to other suggestions:
if(isSmall){
Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
double sh = visualBounds.getHeight();
Scale scale = new Scale(sh, sh, 0, 0);
root.getTransforms().setAll(scale);
}
As has already been mentioned SVG is probably the way to go for you. JavaFX does not support SVG directly but you can find support here
javafxsvg and here svg-to-fxml-converter for example.
You can't resize an image to be bigger than it is without it getting blurry for most common formats. Instead make sure your images are big enough so you only need to downscale them.
The only format I ever heard of that could upscale further was using fractal compression, but AFAIK it is not in common use.
Related
All the images in my app are currently jpg or png, which used to be okay. The GUI was a fixed size appropriate for whatever screen it would be displayed on and everyone was happy.
Now that hi-res and retina displays are more common, the app at its normal size looks small on some screens (or fuzzy if resized), so I'd like to update the graphics to adapt to any future resolution advances by converting them to vector images (eps or svg).
Before I go do this, does JavaFX have a way to use vector images in a similar way to ImageViews? It looks like ImageView itself only supports JPG, PNG, BMP, and GIF.
No JavaFX does not support things like SVG directly but there are solutions like:
- SVG to FXML
- useage of a webview
BTW Image supports hi-res by using #2x notion eg you supply image.png and image#2x.png and JavaFX choose the right one depending on the screen resolution
I'm rendering on screen the game fps using bitmap font but there are no methods for the size. This is a problem for me because my camera viewport size is very small so the text when rendered is huge and pixelated.
font.draw(batch, Float.toString(Gdx.graphics.getFramesPerSecond), x, y);
Did you try setScale() method that what i use to resize my font
myFont.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
myFont.setScale(scale);
if you have trouble, leave a comment
Good Luck !!
Edit :
With the latest libgdx version, try to scale font like this :
myFont.getData().setScale();
I often use what minos23 suggested. But the downfall is that it can look pixelated especially when scaling upwards. A fancy large bitmap font can take up a lot of space and if you need many different fonts you might go over your budget.
By using Gdx.Freetype you are able to create bitmapfonts at runtime from small .ttf files. This means you only need to ship the .ttf files with your app and can generate a font based on user settings like resolution.
Other then scaling and the freetype solution is having multiple bitmaps of different font sizes. This way your fonts stay crisp all time but at the cost of runtime performance to generate the proper fonts.
setScale is the function to use. Please note that with the newest LibGDX version (this changed earlier though) you need to do this isntead:
font.getData().setScale(2, 2);
before it was enough to do:
font.setScale(2, 2);
The first number in setScale is the X scale, and the second is the Y scale.
I use setScale() function too as others to reduce the font size, but here I want to offer another solution and I have a question. Why you don't use FPSRenderer instance or why you don't draw your fps label on another batch which projection matrix has the screen size?
Netero's answer works.
If you want to make code cleaner, you can write a helper function:
public static void setLineHeight(BitmapFont font, float height) {
font.getData().setScale(height * font.getScaleY() / font.getLineHeight());
}
I'm using the itext PDF library to build a very image-intensive PDF document in Java. Each page has a dozen images on it. The original source images are very high resolution, and I'm using scaleToFit to render the image to the size I need.
The problem I have is that the PDF document is still very large. My understanding is that the entire original high resolution image is being included, and the scaling I'm using only affects the actual rendering, not the size of the image that's included in the file.
I've verified this by removing the scaling — the pages were rendered with the high resolution images overlapping each other and the edge of pages, and the PDF was the same size as when the scaling was in place.
So, here's the question — how can I reduce the size of the PDF file by scaling down each image? If I lose a little bit of image quality that's ok. Rescaling the source images manually will be difficult.
So I've found a way to do it. I now load the image into a BufferedImage, and then scale that using the hints found here: how do I scale a BufferedImage.
This gives me a BufferedImage — I then convert this into an iText image using
Image returnedImage = Image.getInstance ( pcb, bufferedImage, quality );
Where quality is currently 0.6. That's acceptable for the work I'm doing.
I am writing a particle based game that is mainly built by drawing lots of colored shapes.
Question 1)
For most of the enemy units I am drawing 4 layered rectangles by setting the paint and then drawing the rectangle through the canvas.
I was wondering if it is better to draw using bitmaps, or to draw using the canvas drawing tools? I could easily make a single image of the enemy unit that I wish to draw.
Question 2)
For the images that I have to draw to the screen, I was wondering how I need to load them?
Right now I have tons of .png images loaded like this:
direction1 = BitmapFactory.decodeStream(assetMgr.open("direction1.png"));
I've read that RGB565 is the fasted image type to draw to the screen. Microsoft Paint has some saving options, but for the most part programs only save as a bitmap, not a type of bitmap. If I was to start using that new format would I:
Make new images and use the same loading code.
Use the same images and add something like Bitmap bmp =
Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); to
convert from the initial loaded format to the RGB565 format.
Make new images and change my loading code.
Thanks for any help! It is very appreciated.
None. It is always better to use OpenGL and the only downside is
that it requires more energy from a battery because it's hardware
accelerated.
RGB565 means that image uses 16 bits so that's the
option you should look for. Don't convert anything, just create them
in the format you will be using.
If the Bitmap aren't moving frame-by-frame, you should try to reduce invalidate() method call. The canvas should only be re-drawn when changes are made and should be updated.
i'm trying to create a program that generates images for use as multi-screen backgrounds, i'm doing this targeted at windows (in my case, 7 so that basically i can get images to change without seeing the same image on two different screens)
in my program, i read multiple image input files and compile them into a single output image that is the total size of the desktop (including black areas not seen on screens)
my question is, what class/methods are good for cropping/resizing/pasting into a new image in java because i'm coming across so many image manipulation classes and they all seem to do one tiny thing.
i will not be modifying any of the images beyond resize or crop and putting it into a certain position in the new (initially blank) image.
code can be made available as i plan to release it at some later point for whoever may like/need it.
thank you in advance, if this question has been answered, my apologies but i DID have a look around.
I do not know if this is the best method, but it is quite easy:
// load an image
Image image = javax.imageio.ImageIO.read(new File("someimage.png");
// resize it
image = image.getScaledInstance(100, 100, Image.SCALE_SMOOTH);
// create a new image to render to
BufferedImage newimg = new BufferedImage(200,100,BufferedImage.TYPE_INT_ARGB);
// get graphics to draw..
Graphics2D graphics =newimg.createGraphics();
//draw the other image on it
graphics.drawImage(image,0,0,null);
graphics.drawImage(image,100,0,null);
graphics.fillOval(20,20,40,40); //making it a bit ugly ;)
//export the new image
ImageIO.write(newimg,"png",new File("output.png"));
//done!
For simplicity I dropped all checks, exception handling, etc.