I am handling a SVG file in Java using Batik library. The problem occurs when i scale it. I can see pixels of lines. Off course this should not happen, i should be able to zoom at least about 4000% and maintain the smoothness.
SVG file is read from an extended class, and it is painted from an override paint method. First i set new scale to AffineTransform variable, apply this to graphics of the method and paint using super.paint().
I am really stuck and can't figure out the problem. SVG files I am using are ok, I opened them in Inkscape and could zoom without the pixels showing. Please help.
code:
#Override
public void paint(Graphics g) {
try {
rad = (int)(radInit*zoom);
updateTransform();
Graphics2D g2d = (Graphics2D) g;
g2d.setTransform(transform);
super.paint(g);
paintElements(g2d);
} catch(NullPointerException nulle) {
// System.out.println("SVG not loaded yet");
}
}
private void updateTransform(){
transform = new AffineTransform();
transform.translate((-1)*zoom*centarX, (-1)*zoom*centarY);
transform.scale(zoom, zoom);
}
What was needed was
this.setRenderingTransform(transform, true);
This way no pixels can be seen or rather, everything is painted as it should be.
Related
I am trying to make some sort of a Paint program but in JAVA. With the graphics class, I can set a painting space and draw on it. I want this space to be an image instead of a white space and despite all my efforts, I can't. If I succeed, I can't draw over the image.
non-working code with image: https://pastebin.com/zNnWGjgS
Stackoverflow forces me to put some code here but it's too long
working code without image: https://pastebin.com/r1nFHY9c
Stackoverflow forces me to put some code here but it's too long
Please help me guys. Thank you.
With just a quick look at you paintComponent I can see that you are confused. All you want to do is to load the graphics of your image into the Graphics2D g2 and draw lines on it. In your non working example you :
Create a new image with createImage(getSize().width, getSize().height);
You set the graphics g2 to empty Image graphics
You load the image and discard the previous initialization leaving the g2 with the empty one.
You drawing the image, while all the changes are made to the g2 graphics.
To fix your error just change the paintComponent to :
#Override
protected void paintComponent(Graphics g) {
if (image == null) {
try {
image = ImageIO.read(new URL("https://i.imgur.com/mjxu50B.png"));
} catch (Exception e) {
e.printStackTrace();
}
g2 = (Graphics2D) image.getGraphics();
// enable antialiasing
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.BLACK);
}
g.drawImage(image, 0, 0, null);
}
PS. In future post try to post the non working example only and try to keep it as simple as you can.
I'm creating a java implantation of http://alteredqualia.com/visualization/evolve/, as a hobby project. I'm using HW-accelerated Graphics2D to draw the polygons on a bufferedImage, which works, but the calling of fillPolygon() so many times cripples the application in terms of speed.
So now my question is: Is there any way to speed up this process?
private BufferedImage createImage() //Gets called once
{
BufferedImage bImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
bImage.setAccelerationPriority(1);
Graphics2D g2d = (Graphics2D) bImage.getGraphics();
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(
RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_SPEED);
this.g2d = g2d;
return bImage;
}
private void reDraw() //Gets called every frame
{
drawBackground(g2d);
for(int i = 0; i < polygonList.getLength(); i++)
{
polygonList.get(i).draw(g2d);
}
}
public void draw(Graphics2D g2d)
{
if(rgba[3] != 0f)
{
g2d.setColor(new Color(rgba[0], rgba[1], rgba[2], rgba[3]));
g2d.fillPolygon(this);
}
}
With the use of java.awt.Graphics there is not much you can do on your end to improve performance except the usual optimizations of Java (reducing object creation and function calls etc). You can however choose how it renders on its end with the RenderHints as I see you are doing; I would suggest you set all the hints to speed including disabling antialiasing because that is actually one of the biggest hits.
Apart from that I can see you are using some array of what I can assume are ints and creating a colour with them, now I'm not sure what class this is from (assuming it's all from one class, please correct me) - nethertheless the if statement could be a return instead (that wont help much), and you should cache this Colour when it changes, I suggest not using the rgba array and using one global Color instance and then use getRed/Green/Blue if you ever need them.
If you would like more advice you can move this to Code Review
Hope this question could emphasize more about the fading out effect of Jlabel (swing).
Certainly, yes... I already follow some guide and some answers given from This Link Thread, but mine is quite a bit different. It's not just only A text inside the JLabel, there's an image i put on.
I proceed to follow on the Thread Located out of stackoverflow. And yet, it gives me a fade out effect. But there's horrible thing occured; the white background.
How to solve this out?
I share the interface here...
The First screenshot taken here is the earlier phase when the fade out have not occured yet. While,
The Second screenshot taken here is the unwanted result i mentioned.
Tobe honest, I used the Trident Library to do animatiing;
So, whenever the user click over the image it will execute this code;
Timeline tm = new Timeline(jll_btnProceed);
tm.addPropertyToInterpolate("intensity", 1.0f, 0.0f);
tm.setDuration(1000);
tm.play();
and... the JLabel itself, I used to override it using this source code;
/**
*
* #author Gumuruh
*/
public class JLabelFader extends JLabel {
private float intensity = 1.0f;
public void setIntensity(float intensity) {
this.intensity = intensity;
this.setOpaque(false);
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
final Composite oldComposite = g2.getComposite();
g2.setComposite(AlphaComposite.SrcOver);
final Color c = getBackground();
final Color color = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (255 * (1.0f - intensity)));
g2.setColor(color);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.setComposite(oldComposite);
}
}
My hand and my head can't stop for making this trully solved. Thus I tried to follow up some example from the Java Filthy Rich Client ebook and then applying the source code given below, but first I need to COMMENT the protected void paint(Graphic g) method written above, and simply adding this source code;
private BufferedImage buttonImage = null;
public void paint(Graphics g) {
// Create an image for the button graphics if necessary
if (buttonImage == null || buttonImage.getWidth() != getWidth()
|| buttonImage.getHeight() != getHeight()) {
buttonImage = getGraphicsConfiguration().
createCompatibleImage(getWidth(), getHeight());
}
Graphics gButton = buttonImage.getGraphics();
gButton.setClip(g.getClip());
// Have the superclass render the button for us
super.paint(gButton);
// Make the graphics object sent to this paint() method translucent
Graphics2D g2d = (Graphics2D) g;
AlphaComposite newComposite =
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, intensity);
g2d.setComposite(newComposite);
// Copy the button's image to the destination graphics, translucently
g2d.drawImage(buttonImage, 0, 0, null);
}
in which at the end... giving me nice fade out effect. But At first, it gave me the 2nd horrible effect which is BLACK BACKGROUND rendered first. Can't believe me?? Okay, Here is First screen shot AFTER applying code from ebook. and here is the nice fade out effect result.
If there's somebody telling me;
"YOUR PNG IS NOT TRANSPARENT!".
Please, dont say like that. Because, I followed the creation of PNG inside the Photoshop nicely using this Tut.
Now, My head's spinned, but my heart laughed and can't handle it over. OMG. Geeezzz....!
And the New Stories begun...
* UPDATED FROM HERE AND BELOW *
Ehm, depply thank you very much to our friend called... MKorbel,
from his thread given at this link. Providing a clear example of fading out effect the Swing JButton and I tried to implement it into my JLabel, and violaaa...!!
IT works.
Let's give a big clap for MKorbel. :D
SO anyway, how could I fix the earlier code? Pretty simple, just COMMENT the Paint() method, and use again the paintComponent() method and it should be overriden with the new source code below;
#Override
public void paintComponent(java.awt.Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, intensity));
if (rectangularLAF && isBackgroundSet()) {
Color c = getBackground();
g2.setColor(c);
g.fillRect(0, 0, getWidth(), getHeight());
}
super.paintComponent(g2);
g2.dispose();
}
Now the JLabel become easy to be changed with its intensity -variable.
Fading out and Fading in is accomplished.
Okay. Now everything seems "OKAY". BUt hold a moment, there's something strangely occured again here. Have you noticed it? Hmmm....
I tried to give a Mouse Event (Hover On) into the JLabel that we override the paintComponent() method discussed earlier.With this line of code;
myJLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
Logically, it should change the Cursor when Hover ON. But, Here comes another strange effect. (Really sorry, but this is stil the continue of the main case). The strange effect now is the Mouse Cursor can't be changed when we Hover On the Jlabel. It still can't change the Cursor. Seems the paintComponent() method effecting the way Cursor react. Is that true?
When I'm rendering a Swing component to an image the fonts are different then when the component is rendered on screen. Here is an image showing the difference:
And this is the code:
public static BufferedImage renderComponent(Component component) {
int width = component.getWidth();
int height = component.getHeight();
BufferedImage buffImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) buffImage.getGraphics();
g.setFont(component.getFont());
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
component.paint(g);
g.dispose();
return buffImage;
}
What should I change to make a perfect screen shot of a Swing component? (The app is running on Windows 7)
What should I change to make a perfect screen shot of a Swing component?
I would guess you should not be providing rendering hints.
I use the Screen Image class for this (it is basically your code with a few other features built in).
After comparing the ScreenImage class (suggested by camickr) I found the cause of the problem. If I create a BufferedImage with the type set to TYPE_INT_RGB instead of TYPE_INT_ARGB the fonts are fine.
Class Robot
public synchronized BufferedImage createScreenCapture(Rectangle screenRect)
?
Im trying to get to grips wth java 2d graphics
Ive basically got a JPanel with a backgrounfd image in it like so:
public MapFrame(Plotting pl){
this.pl =pl;
this.setPreferredSize(new Dimension(984,884));
this.setBorder(BorderFactory.createEtchedBorder());
try {
getFileImage("stars.jpg");
}
catch (Exception ex) {
}
this.addMouseMotionListener(this);
this.addMouseListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bg, 0, 0, null);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(0x756b48));
g2d.drawLine(0,0,0,100);
}
private void getFileImage(String filePath) throws InterruptedException, IOException {
FileInputStream in = new FileInputStream(filePath);
byte [] b=new byte[in.available()];
in.read(b);
in.close();
bg=Toolkit.getDefaultToolkit().createImage(b);
MediaTracker mt=new MediaTracker(this);
mt.addImage(bg,0);
mt.waitForAll();
}
In paint component I want to overlay small images 12x12 pixels in a loop at various xy points that ill get from some xml.
Cant seem to get an image to overlay over my first one
Im a bit lost here and v rusty
Any help would b gr8
public void paintComponent(Graphics g) {
g.drawImage(bg, 0, 0, null);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(0x756b48));
g2d.drawLine(0,0,0,100);
for(SomeXMLObject o : yourXMLSource) {
g.drawImage(yourImage, o.x, o.y, null);
}
}
Please specify clearer how your XML is parsed, if you already did that. Then, you'd also need to load the "12x12" image. SomeXMLObject is a structure containing x and y variables, extracted from your XML.
If you call g.drawImage(...) after the background: it will be painted after the background, and thus overlay. Be sure you load a png-24 image, to enable translucency-areas, if you'd want that.
If you want to paint an image at various locations, it is as simple as calling Graphics.drawImage(Image, int, int, ImageObserver) multiple times for different coordinates (as shown in the previous answer).
As for loading images, I'd recommend using one of the ImageIO.read methods instead of doing it yourself.
You probably want to use use the ImageIO library to load your image. If you have an image filename all you need to do to load it is
BufferedImage bimg = ImageIO.load(new File(filename));
That's a little easier then the code you have above.
After that, like other people said you can use the g.drawImage(bimg,x,y,this); to actually draw the images.
Oh Dear
Id formatted the filenames of my resources wrong
what a donkey I am
All good advice I think though guys