Re: [JAVA2D] createCompatibleImage: why is it faster than creating a Buffered image?
I think I've discovered at least one problem that you are running into - we don't have an optimized loop to convert from 1-bit binary images to INT_RGB images. Further, the general code that gets used doesn't take the best advantage of the existing optimized loops that do exist. We only have a loop to convert from 1-bit to INT_ARGB so if you drawImage directly to an INT_RGB image then it will have to do a slower work-around technique. To find this out (I thought this had been mentioned a couple of years ago on some forum, but I can't seem to find it with a search), there is a hidden utility in the JDK where you can get the system to print out the supported loops. It was originally designed so that you could just execute: % java sun.java2d.loops.GraphicsPrimitiveMgr list and it would print out all of the built-in rendering loops in the system. Unfortunately we broke this at some point and so now it generates an error that a required native method isn't found. The workaround is still simple - compile and run the following very short program and it will do the same thing: public class GPMgr { public static void main(String argv[]) { java.awt.Toolkit.getDefaultToolkit(); sun.java2d.loops.GraphicsPrimitiveMgr.main(argv); } } % javac GPMgr.java % java GPMgr list I grepped for Blit and ByteBinary and discovered that there are only convert (Blit(XX, SrcNoEa, YY)) loops for 1-bit to ARGB. The thing that surprised me, though, was that it took 4 times longer even despite the workarounds. I quickly ran a trace on copying a 1-bit image to INT_RGB and discovered that it ends up using a loop called OpaqueCopyAnyToIntArgb which is a Java loop that uses a couple of method calls per pixel. There are faster ways it could do this, even without creating a specific loop for this case, but it will take a bit of elbow grease as the logic in that part of the system is a little obscure... ...jim === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] createCompatibleImage: why is it faster than creating a Buffered image?
jav...@javadesktop.org wrote: - let us know what image formats you are seeing in the loaded image and which Reader is loading it so we can consider adding loops that deal with that format more directly (or modifying our format detection code to recognize it if there is something amiss with our classifications). We do already have support for a fair number of binary image formats so I'm curious as to what the exact specifics of the format are and why they fail to trigger our existing optimized binary format loops. This should probably be done through the bug tracking system to keep records of the issue... Your comment above seem to indicate that you have optimized loops for reading binary images directly in compatible BufferedImages. Is that correct? There are 2 issues here: - What do you have to do to use a 1-bit image loaded from disk efficiently - How can you efficiently convert it into an efficient format if just using the loaded 1-bit image is slow The first question basically depends on the image reader using only methods that avoid tainting the image so that the returned BufferedImage can be managed. I'm not sure why that is not happening without further investigation, but maybe Dmitri or Chris know what is going on there off the top of their heads. As to the second question, when I looked at the support we had it was pretty sketchy in the Blit support department (see my previous message where I listed the available loops and then looked at what got used by the drawImage call). We have routines for rendering to 1-bit images, but we only have a couple of conversion routines for blitting from 1-bit to another format (to ARGB and back to be specific). So, there is room for improvement there (both in avoiding the very general OpaqueCopyAnyToArgb loop and possibly in adding a few more Blit converters for the format). If yes, then my simple most important question would be: What is the method to read a binary image from a file fast and have a compatible BI in memory? My tests indicate that saving a RGB BI in the BMP format will do the trick, but here is the catch: For now it seems you have to do some conversion and it looks like you've finally arrived at a decent way of doing that short of not having to do it in the first place. I think it's worth filing a bug on the conversion process (really a drawImage should have done the trick without too much fuss, but you had to work around that). We should probably also investigate why the 1-bit image is not being managed so that you don't need any conversion at all. Is it a bug in the reader, or in our image management (caching) code? In any case, you shouldn't have to resort to BMP to work around this - we're so close, let's look at closing the gap on a 1-bit TIFF. So, instead of trying to find out what is the best way to convert, it would be better to know what is optimized and how to use it! I understand that in the general case, the average jdk developer does not need to know what you optimize and what not, but it would be a great idea to publicize this info (even unofficial, i understand that you wouldn't want to write this in stone). I think my previous message mentioned some tools for programmers to get a glimpse into what we've targetted with direct implementations vs. what we do with general workaround code... ...jim === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] createCompatibleImage: why is it faster than creating a Buffered image?
jav...@javadesktop.org wrote: Thank you Dmitri for your answer. Let me just say a bit more of the problem and why i go to this method: My goal is to find the faster way to load an image from the disk (a tif file, either binary or colored) and display it on the screen in a compatible way (e.g. fast to redraw, pan, zoom, etc). From all the reading i have done, i have concluded that i need to: 1. Load the image with ImageIO 2. Convert it to compatible 3. Display. 1. Converting an image to a compatible one is always faster with a ColorConverOp than with a g.drawImage. At times the speed is the same, but in general, the ColorConverOp is always a bit faster. Both ColorConvertOp and drawImage have a set of image formats that they handle directly with optimized loops (all native code), and other formats that they use generalized code that may be as slow as making a method call per pixel. You seem to be running into cases where CCO has optimized loops, but drawImage does not. We tend to look to add loops for drawImage to handle common image formats that come up for our developers, but we need to avoid adding too many special case loops and bloating the JDK. What is really interesting is this: if an images already uses a SinglePixelPackedSampleModel then the ColorConvertOp is significantly faster (more than 50%). What is the image format you are using in the TIFF file and what are the parameters of the *Models it uses to represent it in memory? (Before you start converting it.) 2. So the question remains: a. Is it faster to convert directly to compatible using g.drawImage, or b. is it faster to create an unmanageable image with a SinglePixelPackedSampleModel and then use the ColorConvertOp to make a compatible out of it? g.drawImage() has optimized loops to convert from some common image formats to destination images in some other common image formats. If you fall into one of those categories then it makes sense to use that. ColorConvertOp also has its own set of loops as well. With respect to SPPSM, it isn't so much about that particular sample model than about which parameters you use with it. When we classify an image internally we examine not just the type of the SampleModel and ColorModel, but what masks, offsets, and other parameters they use. g.drawImage() is one of the simplest techniques, and for occasional use, or for use at application startup for most image sizes any potential performance issues with that technique are probably not noticeable. But, if you are doing this to a lot of images on the fly, then it is worth optimizing this step some more (and pushing to have the internal drawImage() code support it more directly as well). This is why i use it. Empirical results are often the best guide here, but let me present some rules of thumb which might help make the choices easier (to make, or at least easier to understand) and point out some potential other alternatives. First, some details about the implementation: - If you grab the DataBuffer from an image, it becomes unmanageable in JDK 6 and prior. This would recommend using the various WritableRaster methods to write data to the images if you want to remain manageable, or using a conversion process. This is also true if you have a DataBuffer and make a BufferedImage out of it. - In JDK 7 and beyond we now track the pixels at the DataBuffer level so you can grab the DataBuffer and use its methods to modify or access an image, as long as you don't grab the array itself from the DataBuffer. For instance, creating a DataBuffer using your own array automatically disqualifies the image from being manageable. This gets you much closer to the raw data without disrupting the cache management, but only works on JDK 7 and forward. - Manageable images, as you seem to already be aware, can be hardware accelerated via cached copies kept in VRAM on platforms that support it, so it is good to use techniques that maintain that property if they work well enough, otherwise doing what works best even if it defeats image management and using the old convert to a compatible image after the fact technique becomes necessary. - As I stated above, drawImage has a matrix of optimized from/to image format pairs it supports well for doing software copies and conversions. These copies are going to be slower than a hardware copy, but much faster than the code that deals with arbitrary from/to images which often breaks down to a per-pixel method call. - Also, as stated earlier, ColorConvertOp also has a matrix of from/to formats, but it is implemented using an entirely different system than drawImage and so the matrix is unrelated. This Op may also need to resort to per-pixel method calls if you fall outside its matrix. - The most likely candidates for support in the matrices above would be the formats created using the new BufferedImage(w,h,TYPE_FOO) constants. It looks
Re: [JAVA2D] -Dsun.java2d.trace=count not providing output
Dmitri already pointed out your problem with the placing of the command line options, but I wanted to mention some issues with the options you were using: I don't think opengl=True provides trace output (Chris?). I think all it does is it prints a message saying Yes, indeed, I did successfully enable the OpenGL pipeline at startup and that's it. Also, only some output is included in the production builds for J2D_TRACE_LEVEL. Most of the code that honors that is #ifdef'd DEBUG. Finally, sun.java2d.trace=log can be used to log each operation as it occurs... ...jim jav...@javadesktop.org wrote: Hi All, I'm creating a GUI that uses a custom skin using Synth. I would like to know more about how I can determine how much rendering is being done using the hardware acceleration on my machine. I've found that the Java 6 SE Troubleshooting Guide has some suggestions on how to do this. It mentions that the [b]-Dsun.java2d.opengl=True[/b] setting (with a capital T) can be used to switch to using the OpenGL pipeline with trace output enabled. Another setting [b]-Dsun.java2d.trace=count[/b] provides a summary of primitives used that is dumped on application exit. The problem I've having is that these system properties don't provide output for me - I don't see any trace output on the console. The steps I followed are: 1) compile the GUI to a jar, [b]gui.jar[/b] 2) [b]export J2D_TRACE_LEVEL=4[/b] 3) try [b]java -jar gui.jar -Dsun.java2d.trace=count[/b] - jar runs but no trace counts on exit 4) try [b]java -jar gui.jar -Dsun.java2d.opengl=True[/b] - jar runs but no trace provided during run The GUI is skinned using images and Java2D primitives so I expect that the mix of graphics routines would invoke hardware acceleration of some kind. Is there something I'm missing here? Were these system properties perhaps removed for the update 10 stable builds? I've tried this with Java 6 update 10 and update 13. Interestingly, the GUI ran very slow on update 10 without the [b]opengl=True[/b] setting but not in the case of update 13 so I'm assuming 13 came out with more optimised / accelerated routines. Also the [b]opengl=True[/b] setting provided some output on update 10 but not on update 13. I've tried this on Ubuntu Jaunty (9.04) and Hardy (8.04). My graphics card is a NVidia GeForce series card. Thanks for reading, Mark [Message sent by forum member 'bowsermail' (bowsermail)] http://forums.java.net/jive/thread.jspa?messageID=347167 === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help. === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] Exactly which graphics surfaces get HW accelerated?
Can ADD and MULTIPLY be expressed using Porter/Duff equations as per the existing rules? I seem to recall that they require clipping the result which none of the other modes require. The P/D chapter in Foley and vanDam mentiones PLUS, but it doesn't describe it in the same terms as the existing table of rules. It is more described as another useful binary image operation. Keep in mind that the existing P/D rules for AC are all implemented using a single loop at the bottom end that has a tiny variation in it that handles all 12 or so rules in the same piece of code with little structural change. Note that when I say a single loop I don't mean a single piece of code that is factored with macros into 12 loops, but a single actual compiled object function that handles all 12 rules. It doesn't even have any decisions in the inner loop for the 12 rules - instead it relies on mathematical similarities of the 12 rules to handle them all with a single computation. So, if you want to add new rules to this matrix, they might not fit into this technique and induce an explosion of the code that handles the AC rules. The technique only really deals well with rules that can be expressed with the 4 standard Fa and Fb functions that are guaranteed not to overflow in the math. If you add rules that are incompatible with that technique then it is more likely that you'll have to special case them and vector them into new inner loops that do whatever clipping/clamping is required for ADD/MUL that isn't required for the regular AC rules. That isn't a huge issue, but it might almost be cleaner to have a new class so we vector into different code paths at a higher level than to have to vector off at a lower level. (Try it and see how it goes). ...jim jav...@javadesktop.org wrote: Hi everyone, quick question more or less related to this topic on hardware accelerated drawing: I was desperately waiting for what was supposed to be called the PhotoComposite API that would allow new blending modes (ADD, MULTIPLY, OVERLAY, ...) to be used as Composite for the Graphics2D API. Unfortunately, it seems that the original plan is no longer in scope as stated in the RFE 6541868 (RFE: hardware acceleration for advanced blending modes (aka PhotoComposite) ): [i]Therefore, my current inclination is to scale back the changes originally proposed for JDK 7 and instead make small additions to the existing AlphaComposite API with at least an ADD mode since a) that is the most commonly requested blend mode that isn't already provided in AlphaComposite, b) it fits in fairly well with the existing AlphaComposite rules, and c) it can be accelerated easily in both the software and hardware pipelines (without the use of shaders or reading back from the framebuffer in the hardware case). We might also be able to add a simple MULTIPLY mode, but that will require some more investigation. I think this approach (small enhancements to AlphaComposite) would serve the needs of Java2D developers quite well, while keeping the implementation burden low. Developers who want access to extended blend modes can use the Blend class from JavaFX, which offers the right amount of functionality in a form that can be easily accelerated on the GPU.[/i] Having ADD and MULTIPLY as Composite for Graphics2D is much better than nothing as they are usually the most useful advanced blending modes. My problem is that I am working with the BufferStrategy to perform fast frame rate in fullscreen mode. And when using the BufferStrategy, I cannot access to the actual offscreen backbuffer to use it with the JavaFX Blend implementation that will give access to the other hardware accelerated blending modes. As stated by Dmitri, using a VI and then drawing it with the BufferStrategy is not really satifying... This is why having the Graphics2D API able to use all the wonderful hardware accelerated drawing features of the JavaFX package would be very nice... If you see some kind of workaround for me to use JavaFX API with the BufferStrategy without using an additional backbuffer, I would be very interested ! Thanks. Vincent. [Message sent by forum member 'vync79' (vync79)] http://forums.java.net/jive/thread.jspa?messageID=340922 === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help. === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] Transparency rendering problems
This is probably due to the fact that we use different rendering pipelines in some cases when the colors are translucent (for example, we may use X11 requests to render on Linux and Solaris when the colors are solid, and then we may use readback, modify pixels, writeback mechanisms to deal with translucent requests. Sometimes the exact pixel-for-pixel rasterization of the two pipelines doesn't match. It is a bug, but the fix may be hard. If you could submit a bug with a smaller (standalone) test case then it could be tracked... ...jim jav...@javadesktop.org wrote: Hi all, I have a weird problem which may be a bug, but hopefully has a solution. I am drawing a histogram whose bins are coloured according to an arbitrary colour map. This involves drawing a series of filled rectangles whose height is proportionally to the frequency of the bin, and then drawing an outline across the tops of these rectangles. This works fine for colour maps with no transparency; however, when I want to apply transparency to the rectangles, they render incorrectly, and in a seemingly unpredictable way (see this image: http://www.typically.net/FTP/histogram_bug_all.png ). The exact same code is used to render both instances, which is why I'm thinking this must be a Java2D bug... The rendering code (where g is the Graphics2D instance) is: === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] Flip and draw an image by graphics.drawImage(..): Any issues known?
If I understand your question correctly, you are saying that the performance meets your needs, so you are mainly asking if there are any hidden gotchas in that API? If we are in a hw accelerated pipeline then I think the flipping is probably guaranteed to be free since image transformation is accelerated naturally and cheaply by most any GPU. If we are in sw then the code will end up in the image transform pipelines which have slightly more overhead than the straight copy loops, but probably nothing noticeable when compared to manually flipping the image through any other means. On the other hand, if you are dealing with the results of a 3D scene then I'm guessing you are only concerned about running on a 3D accelerated GPU and so the prior comment about it's free on HW is the more germane comment... ...jim === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] Is there a bug with clipping and affine transforms?
jav...@javadesktop.org wrote: First, note what the API doc says about setClip(Shape clip): [b]Not all objects that implement the Shape interface can be used to set the clip. The only Shape objects that are guaranteed to be supported are Shape objects that are obtained via the getClip method and via Rectangle objects.[/b] That's a red herring. It was in there for the 1.1 days when we introduced Shape, but before we could handle arbitrary geometry in the rendering routines. It should have been removed in Java 2, but we didn't notice it until recently. It lives on in one of those the next time someone is in that file, please remember to delete this line limbo phases, but we have little reason to edit that file any more... ...jim === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] How to check intersection of Shape contour and Rectangle2D?
The BasicStroke.createStrokedShape() is the intended method to test for intersection with the stroked shape as you implemented in your later example. Note that the default graphics setting for the STROKE_CONTROL hint is STROKE_NORMALIZE which allows tweaking of lines for aesthetic purposes which may not exactly match the output of createStrokedShape(). If you render with STROKE_PURE for that hint then the output should be much closer. On the other hand, your UI may not really be affected by an off-by-1 error caused by the normalization procedures so this may be a moot point... ...jim === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] Is there a bug with clipping and affine transforms?
Note that, in Java 2D, a shape cannot know its outline design because that depends on another graphics attribute - the Stroke object. The default implementation of that interface is a BasicStroke object with a line width of 1.0f, but that is just the default for the Graphics objects you get from images and components. A different implementation of Stroke may behave entirely differently and a graphics retrieved from a different context may have a different default setting. Thus, to get a result that includes the Stroke you have to consult the Stroke object that will be used to render the object. It implements a createStrokedShape() method, part of the Stroke interface, to return the shape that defines the area to be painted when a given Shape is stroked by that object. If you just want the bounds with the stroke included (as opposed to the actual shape that will be stroked), and if you know that you only ever plan to use a BasicStroke object with a simple line width, then it might be simpler to just take the bounds of the shape, pad it by linewidth / 2 on every side, and use that. Unfortunately this approximation does have its limitations - the default JOIN attribute on BasicStroke is a MITER stroke which can extend more than lw/2 units away from the shape, depending on how sharp any of the angles in the shape are. To predict if this comes into play you should read up on the subject of MITER joins and the miterlimit attribute. Or, if you are using ROUND or BUTT joins then the lw/2 padding is sufficient for their operation. Another potential caveat is that the default setting for the STROKE_CONTROL rendering hint, which controls tweaking an outline for aesthetic purposes, is STROKE_NORMALIZE which allows the rendering algorithms to tweak the outline by up to a pixel to increase the chance of consistent line thicknesses. Setting that hint to STROKE_PURE requests that no such normalization occur during rendering... ...jim jav...@javadesktop.org wrote: Hi Piet, Thank you for your input and suggestions. I also discovered that the problem can be avoided by expanding the clip region but this example with the rectangle is only the very simplest case of the overall problem I am facing. I have found that this problem applies with shapes of all kinds and complexity and expanding the clip region is not so easy given that the shape is not a simple rectangle. How can I solve this problem in a more general sense with more complex shapes? [Message sent by forum member 'qu0ll' (qu0ll)] http://forums.java.net/jive/thread.jspa?messageID=326980 === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help. === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] BufferedImage.getRGB BufferedImage.setRGB
What format are you saving it as? Note that the JPG image format is lossy so the image written to disk might be different from the image you handed to the writer (off by 1s would be common). PNG is a lossless format so it will write out exactly the pixels you hand to it. Also, what format is the incoming image? If it is TYPE_INT_RGB then you don't need to worry about the alpha component as it has no alpha channel. You only need to extract and return the alpha component if it is a type that has alpha, like TYPE_INT_ARGB. If it is not one of those 2 types then you might need to do more work with the pixels, but I'm guessing that it really is one of those 2 types if you are getting this far... ...jim jav...@javadesktop.org wrote: Krill, Thanks for the suggestion, I have tried this, and where as the pixels in the image are showing as blue when I reload the image non of the pixels have their blue component set at 255, I am manually setting alpha = 255 red = 0 green = 0 blue = 255 however blue is being set to 254 alpha remains at 255 and red and green remain at 0 So it is almost working. I shoule be able to set the blue to 255 shouldn't I ?? Regards, Chris [Message sent by forum member 'cocopopsicle' (cocopopsicle)] http://forums.java.net/jive/thread.jspa?messageID=325862 === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help. === To unsubscribe, send email to lists...@java.sun.com and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to lists...@java.sun.com and include in the body of the message help.
Re: [JAVA2D] apply changes to buffered image
I have some general comments about the code you included. Hopefully they can help you figure out the problem you are having... [EMAIL PROTECTED] wrote: I have a question If I have a buffered image. I apply some changes to the image, such as smoothen the image. How can I display the new image. Here is a snippet of my source code. Because everytime I apply the the new image. The only thing is see is my original image. What are the few things to keep in mind to update an image(i.e.)after using setrgb() [code] class MyPanel extends JPanel { //Purpose: a panel in which to draw //global offscreen and the Graphics2D variable g2 private BufferedImage bufImag; protected Graphics2D g2; private int x,y; final int offScrWidth=1500,offScrHeight=1500; public MyPanel() { bufImag = new BufferedImage(offScrWidth,offScrHeight,BufferedImage.TYPE_INT_RGB); This statement doesn't seem to serve any purpose because the following lines of code will replace bufImag with a new reference to a different image...? try { InputStream in = new FileInputStream(Skull.JPG); bufImag = ImageIO.read(in); This line of code causes a brand new BufferedImage to be created and to be stored in the field named bufImag thereby replacing the reference to the image you created a couple of lines earlier. The contents of this new image will be initialized from the data read from the Skull.JPG file synchronously before the read() method returns. At this point, bufImag contains the image that was in the file. } catch (IOException ex) {} g2 = bufImag.createGraphics(); This creates a graphics object that can be used to render onto the image you just read from the Skull.JPG file. That image already has some perfectly good contents which were read from the JPEG file so I'm not sure why you would want, or need, to render onto it...? setPreferredSize(new Dimension(offScrWidth,offScrHeight)); g2.drawImage(bufImag, 0,0,null); The g2 graphics object was created above from the image read from the file so it will render into that image. Here you asking that graphics object to render bufImag onto it, but that is the same image that the graphics was created from - so, in essence you are asking this graphics object to copy that image onto itself. Luckily this has no effect so you wouldn't notice a problem here, but it is wasted effort so this line could easily be deleted. } public void smoothme () { int sum=0; int width=bufImag.getWidth(); int height=bufImag.getHeight(); int[][] pixels = new int[width][height]; int I,J,i,j; for (J=0;Jheight;J++) { for (I=0;Iwidth;I++) { pixels[I][J] = (bufImag.getRGB(I,J) 0x00ff); This will extract the blue channel from every pixel in the image and store it in the pixels array. (Also, note that you are using 32 bits per pixel to store only 8 bits of data, which is a waste of storage.) } } bufImag = new BufferedImage(offScrWidth,offScrHeight,BufferedImage.TYPE_INT_RGB); //set of codes for processing the image for (J=0;Jwidth;J++) { for (I=0;Iheight;I++) { bufImag.setRGB(I,J,((pixels[I][J]8)+pixels[I][J]8)+pixels[I][J]); After consulting with the operator precedence table I think this code is simply copying the data that was taken from the blue channel of the original image into the red, green, and blue channels of the new image. Was that the intent of the code? I'm not sure how that operation would be considered smoothing? } } g2.drawImage(bufImag, 0,0,null); The object g2 still points to the original image, but the bufImag field now points to the image you just filled with new data. This operation will copy the new data you calculated into the old image, which is no longer referenced anywhere so it doesn't do any good to perform this copy. What was the intent of this line of code? repaint(); } public void paintComponent(Graphics g) { //Purpose:
Re: [JAVA2D] Print BufferedImage Externally Generated
Phil already talked about why you are having resolution problems, but I wanted to point out a mistake in your code that was causing some of the operations to be lost. [EMAIL PROTECTED] wrote: Hi, I'm trying to build up a BufferedImage using its Graphics component, and then print that image using a Printable. The problem is that some of my operations on the graphics component seem to be lost, and when I print the image, a lot of it is clipped off around the borders. The code below shows the gist of what I'm doing. // this method is in class A foo(String text, Font font, B b, int x, int y) { Graphics2D g2d = (Graphics2D) image.getGraphics(); g2d.setColor(Color.black); // this color gets lost when bar is called g2d.setFont(font); // this font gets lost when bar is called b.bar(text, x, y); In this code you never use g2d to draw anything. You call getGraphics() on the image, which constructs a brand new Graphics object that is not shared with any other call to getGraphics() and then you set some attributes (color and font) on that graphics object and then you drop the reference on the floor so those attributes will never get used anywhere to draw anything. The key things here are: Image.getGraphics() always returns a new object that is never shared. Graphics.setColor() sets the color for only that one graphics object, it has no effect on any other graphics object. (The same is true with setFont()). } // this method is in class B bar(String text, int x, int y) { Graphics2D g2d = (Graphics2D) image.getGraphics(); Here you obtain another brand new unshared graphics object from the image which is set to default values for all attributes. In particular, this object will not have the color or font that you set in foo() because those attributes were set on a different graphics object. g2d.drawString(text, x, y); // this does not get lost when the image is printed } // this is the print method for the Printable, the image is passed to the Printable print(Graphics g, PageFormat pf, int pageIndex) { if (pageIndex == 0) { Graphics2D g2d = (Graphics2D)image.getGraphics(); g2d.translate(pf.getImageableX(), pf.getImageableY()); Here you obtain a 3rd graphics object from the image and you set its translation. But, again, since you never draw anything with this g2d, the translation you set never gets used for anything. ((Graphics2D)graphics).drawImage(image, null, 0, 0); Finally here you use some other graphics object (it isn't the one that was passed in to the print method - that one was called g - and it isn't the one that was obtained from the image - that one was called g2d, so I'm not sure where you are drawing this image to - it's being drawn to this mystery object called graphics that none of the code you included traces the creation of...? return Printable.PAGE_EXISTS; } else { return Printable.NO_SUCH_PAGE; } } If I hardcode the color and font in the bar method, then the text actually comes out at the printer, but if x 80 or x 500, it doesn't get printed; same if y 80 or y 600 (these are approximate, I'm just estimating based on what I printed and where it got cut off). This leaves about a 1 inch margin around the printed text on the paper from the printer. Ultimately, I want to generate a document image using j2d and send that to the printer. Any help is greatly appreciated! My comments above should help you realize why putting the color and font into the bar method is quite a different set of operations than trying to do it from the foo() method. You cannot leave some attributes in a graphics object to be used by future graphics objects because each call to getGraphics() returns a brand new instance with preset defaults. ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Poor performance of Java2D
Answers inline... [EMAIL PROTECTED] wrote: Sorry, fixed now. And several questions about the code. 1. Save/Restore of transformation in Graphics2D. Is this way: AffineTransform saved = g2d.getTransform(); ... g2d.setTransform(saved); efficient??? It works well for 1 or 2 attributes, but if you are going to save more than that then this way is simpler and still fast: Graphics2D g2 = g.create(); g2.setAttribute[s](...); g2.drawandfillstuff(...); g2.dispose(); Some people may find that model simpler even for one attribute. A lot of work went into making Graphics2D.create() very fast since Swing uses that method a lot. 2. Fill/Draw functions. I often use fill and draw functions for the same path. Can this somehow be optimized? In Qt there is only one call to QPainter::drawPath and it simultaneously uses current pen for outline and current brush for filling. We don't have any fill and draw convenience functions or separate fill and draw paint attributes. I don't think I've seen any feature requests for these before either. 3. I didn't find Path2D.arcTo and used Path2D.append(new Arc2D.Double(...), true). Is this intended way to add arc to path? [Message sent by forum member 'kamre' (kamre)] Yes, that is the only way to add an arc to a path currently. There was a suggestion to add that method to GeneralPath (now just a subclass of Path2D), but it never received any votes in the bug parade in over a decade: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4080460 ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] area.subtract and antialias problem
Since the 2f stroke straddles the path it only contributes 1f on every side so the 96pixel ellipse should be 98 pixels. It should be reliable on all platforms, but there may be +/- half a pixel slop depending on rounding directions, stroke normalization hints and algorithm choices. Yes, translucency does ruin the drawing shapes on top of each other approach. At that point the only choices are to let the background leak through or use a downsampling approach in place of the built-in AA. BTW, have you tried setting the STROKE_PURE hint? That may at least make the gaps a little more symmetric than the default STROKE_NORMALIZE hint... ...jim davood wrote: Thanks for your helps. The problem with drawing the border is that it will make the size of shape bigger than what it actually is, specially if I use stroke 2f. Can I be sure that if I draw a say 96pixel ellipse and a 2f stroke around it, it will take 100pixel on all platforms? On other side the shapes will be translucent so its not possible to just draw shapes on top of each other. Beside that I need to measure shapes area and there will be user interactions, It's why I'm trying to find a solution having the exact shape. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] area.subtract and antialias problem
Since both shapes are being rendered with an opaque color, why not just render shape1 followed by shape3? The problem you are running into with antialiasing is a common one and it is due to the fact that the two operations work independently to fill C (for fraction of coverage) of the pixel and then again to fill (1.0-C) of the pixel. Geometrically you can see that the two operations should be filling wholly separate parts of the pixel and so the new coverage should be a full 1.0, but the operations are done in isolation and so filling C of the pixel in the first operation leaves it C filled and (1.0-C) remaining from the original background color. The second operation then comes along and fills against the blended color and ends up leaving some of the background still showing: bg = original background color c1 = color of first fill operation ci = intermediate color after first fill operation c2 = color of second fill operation cf = final color C = coverage of first shape 1-C = coverage of second, subtracted shape First operation (fills the pixel with coverage C): ci = C * c1 + (1-C) * bg Second operation (fills again with coverage 1-C): cf = (1-C) * c2 + (1-(1-C)) * ci = (1-C) * c2 + C * ci = (1-C) * c2 + C * C * c1 + C * (1-C) * bg If the coverage was 0.5 then the background should still be contributing to 0.25 of the color of the pixel. Note also that the first color is also only contributing to 0.25 of the pixel and the second color is the only one with a proper contribution at 0.5 of the pixel. The only workarounds are: - Render the entire scene non-antialiased at a higher resolution and then use image subsampling in stages on the fully rendered image to downsample while blending to create a full scene antialiasing technique - Render a fringe around the second operation so that it fully bleeds into its border pixels and then render the first operation on top of it so that it correctly replaces exactly the C portion of the pixel and leaves the remaining 1-C portion set to the second color. (Someone already suggested this technique here, but I am adding a little to it by saying that it works better if you perform the second fill first with its fringe and then have the first fill done in AA mode on top of it.) Hope that helps! ...jim davood wrote: Hi, In my application I'm creating new shape (Area) by subtracting a shape from another one but when I turn on the antialias in rendering I face with a white border around inner object. I'm not using composite because I need to create the shape by subtracting. Is there any solution for this problem? Here is a sample code, private void drawTest(Graphics2D g2) { g2.setColor(Color.WHITE); g2.fillRect(0, 0, getWidth(), getHeight()); Ellipse2D shape1 = new Ellipse2D.Double(150, 185, 150, 60); Shape shape3 = new Rectangle2D.Double(100, 100, 250, 250); Area area = new Area(shape3); area.subtract(new Area(shape1)); g2.setColor(new Color(86 / 256f, 114 / 256f, 142 / 256f, 1f)); g2.fill(area); g2.setColor(new Color(86 / 256f, 144 / 256f, 182 / 256f, 1f)); g2.fill(shape1); } === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Is there an optimized way to draw shapes with a gradient stroke ?
Unfortunately the Stroke interface in 2D is defined as just a geometric effect - it can turn a Path into an outline to fill, but cannot specify any color properties for the result. As a result, there would be no custom Stroke implementation you could use to achieve this result and I can't think of any better ways of doing it than what you did short of writing your own rendering function(s)... ...jim [EMAIL PROTECTED] wrote: Hi, in my application, I need to draw a shape with Graphics2D methods where the Stroke used is not a uniform color but instead some kind of gradient from solid color to semi-transparent color with a given thickness. The current way I am dealing with this is to draw the shape several times, each time with wider and more transparent stroke. This way I pretty much achieve the effect I wanted. However, this operation has to happen around 40 times per sec on quite a lot of shapes... I would like to know if there is a faster way I am not aware of that could do this in one single drawing path. In other word, is there a kind of GradientStroke that could be used as argument for the Graphics2D.setStroke() method. Regards. Vince [Message sent by forum member 'vync79' (vync79)] http://forums.java.net/jive/thread.jspa?messageID=303211 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Optimizing concentric arcs
In other words each new arc is effectively underneath all of the previous arcs? You could use intermediate images for this. Create 2 INT_ARGB images the size of your drawing (or the portion with this waterfall-ish effect). On each frame you have the one that holds all of the previous arcs and the one that you will draw the new arcs into. Then you simply do: BufferedImage oldframe; BufferedImage newframe; ... loop { Graphics2D g = newframe.createGraphics(); if (need to clear new frame) { g.setComposite(AlphaComposite.Clear); g.fillRect(0, 0, w, h); g.setComposite(AlphaComposite.SrcOver); } g.setColor(...); g.fillOval(...); /* or g.fill(Ellipse2D); */ g.drawImage(oldframe, 0, 0, null); g.dispose(); ... render newframe to destination ... BufferedImage tmp = newframe; newframe = oldframe; oldframe = tmp; } If your arcs are all opaque and each one is bigger than all of the previous ones then you don't need the clear part, but if drawing the new arc on each frame doesn't obliterate all of the old stuff drawn there, then you should clear it for good measure... ...jim [EMAIL PROTECTED] wrote: In an animation component that I am writing I have to draw colored concentric arcs. In each frame I draw a new outer arc, and the inner arc is what in the previous frame was the outer one and so on. (To help you understand, if I was drawing straight lines, instead of arcs, this would give a waterfall effect). In the attached program, I am drawing as many concentric arcs so as to complete a circle. The problem is that with each successive frame the rendering time increases to such an extent that this algorithm is unusable. Is there any way to improve the performance without reducing the diameter of the whole circle (1000px) and/or the angle of each segment (1 degree). (Note that if the segment angle is 90 degrees the performance is pretty bad too.) If I were drawing lines instead of arcs the optimisation is easy, I’d just copy the previous image down one pixel and then paint the new top line. But with arcs I’m have to issue a drawArc() for every arc that has to appear. I hope that somebody has some idea on how to optimize this. [code] package waterfall; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Arc2D; import java.util.Iterator; import java.util.LinkedList; import java.util.Random; public class WaterfallArc01 extends javax.swing.JPanel { private final int diameter = 1000; // pixels private final int sectorExtent = 1; // degree; private final int numberSectors = 360/sectorExtent; Random seed = new Random(); LinkedListColor[] list = new LinkedList(); public WaterfallArc01() { ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { generateNewData(); repaint(); } }; javax.swing.Timer t = new javax.swing.Timer(500, taskPerformer); t.start(); } private void generateNewData() { Color[] sectors = new Color[numberSectors]; for(int i=0; inumberSectors; i++) { sectors[i] = getColor(); } list.addLast(sectors); if (list.size()diameter/2) { list.removeFirst(); } } private Color getColor() { return new Color(seed.nextInt(0x100)); } @Override protected void paintComponent(Graphics g) { render(g); } private void render(Graphics g) { Graphics2D g2d = (Graphics2D)g; long startTime = System.nanoTime(); int size = diameter; int x=0; int y = x; double startAngle=0; double oldX=x; // Erase background to white g2d.setColor(Color.BLACK); g2d.fillRect(0, 0, diameter, diameter); Color[] sectors; IteratorColor[] it = list.descendingIterator(); while(it.hasNext()) // each update { sectors = it.next(); for(int i=0; i sectors.length; i++) // all sectors { g2d.setColor(sectors[i]); g2d.draw(new Arc2D.Double(x, y, size, size, startAngle, sectorExtent, Arc2D.OPEN)); startAngle += sectorExtent; } oldX = x; do{ size = size - 1; x = (diameter - size)/2; } while(x == oldX); y = x;
Re: [JAVA2D] Optimizing concentric arcs
Are these 1-pixel wide arcs or wider? Currently we have 2 different paths for drawArc. If we determine that the stroke size is less than or equal to a pixel then we trace along the arc and use a bresenham-like algorithm to touch the pixels. If it is wider then we invoke a line widening algorithm which takes the original arc path and computes a path which surrounds the pixels touched for stroking it. This widening algorithm can take comparatively much longer to run than a simple single pixel arc or a filled arc. If you want to get a fast ring to draw, it would be better to create a path which can be filled to draw it. You would draw CW for the outer part of the ring, then draw a line towards the center, then draw another arc CCW for th inner part of the ring and close the path. Calculating and filling that path would go much faster than drawing an arc with a wide stroke. The Arc2D class can generate bezier paths for arcs of arbitrary size, but it always generates them in the same direction so it would be hard to use it to do the above. Alternatively you can google for the math to create bezier curves to draw an arc - the math is pretty simple - and create your own GeneralPath manually. Hope that helps... ...jim [EMAIL PROTECTED] wrote: Well, this seems really hard to optimize ... tons of very small primitives. i've calculated that when i'm dealing with a full set of data, thats after 250 frames, i need to do 90,000 draw-Arc calls. The only advice I can give you is to grab the Raster of a INT_RGB buffered image: byte[] data=((DataBufferByte)tex.getRaster().getDataBuffer()) .getData() (in your case its an int[] of course), and write code that does the drawing on the pixel-array itself. It should be really fast to colour those few pixels if you don't have to walk through a general framework, but instead do exactly what you need and that optimized. The downside of course is quite a lot of hand-written low-level code. lg Clemens [Message sent by forum member 'ser207' (ser207)] http://forums.java.net/jive/thread.jspa?messageID=301129 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Scaling using java.awt.Image is vay faster than bufferedImage. But Why?
Hi, [EMAIL PROTECTED] wrote: And here infos that you asked; İmage info: [EMAIL PROTECTED] //source image that i get with Jimi. As I read this you are saying that Jimi returned to you a ToolkitImage. Is that correct? I think that was to be expected. Unfortunately printing a ToolkitImage doesn't give any clues as to its internal format like printing a BufferedImage, but we can figure it out from the trace log (see below). Run time: getScaledInstance() : 718 ms This is the run time for running your scaling method on the Jimi image, correct? //the returning scaled result as buffered image BufferedImage info : [EMAIL PROTECTED]: type = 1 DirectColorModel: rmask=ff gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 780 height = 1102 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0 What is this image? Is it the result of running your scaling method on the Jimi image? If so, then this is not what I was asking for - we already know the format of that image, because it is constructed manually in the scaling loop (the call to the BufferedImage constructor). INT_RGB are one of the standard formats which are well supported in our registered graphics loops. What I was really asking for is what kind of image you get back from the ImageIO.Read call. and here the trace result; There was a lot of extraneous information in your trace result. Obviously there is a lot going on in your program and most of it has no bearing at all on what is making the scaling method run slower for the ImageIO image. I just wanted the few logged operations that occured while running your scaling method. If I can make an educated guess without knowing your program, I would say that would be the following lines: İmage info: [EMAIL PROTECTED] sun.java2d.loops.TransformHelper::TransformHelper(Index8Gray, SrcNoEa, IntArgbPre) sun.java2d.loops.TransformHelper::TransformHelper(IntRgb, SrcNoEa, IntArgbPre) Run time: getScaledInstance() : 703 ms BufferedImage info : [EMAIL PROTECTED]: type = 1 DirectColorModel: rmask=ff gmask=ff00 bmask=ff amask=0 IntegerInterleavedRaster: width = 780 height = 1102 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0 Run time: init() first scale Render: 1078 ms and the rest of the log after that looked like other assorted graphics calls that were happening later in your program. Is that correct? From the above it looks like Jimi returned you an 8-bit grayscale indexed image. (Printing a toolkit image doesn't print its internal format, but you can infer the format by looking at the source image type in the first TransformHelper operation.) I'd be curious to see what kind of image is being returned from ImageIO for your images and what loops are being used for the duration of the scaling method (i.e. just an abbreviated log showing the operations incurred during that one method). I'm guessing it uses a less optimal format for which we might not have TransformHelper loops defined, but I need to know the image format and the loops that were used to provide any more specific information... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] BufferedImage with transparent background
If you are using JComponent.paintComponent() to render into your image then it will render the background color unless you turn that off. You might want to start with this article for some pointers/tips: http://java.sun.com/products/jfc/tsc/articles/painting/ ...jim [EMAIL PROTECTED] wrote: Hi everybody !!! I have a serious problem on my image. Well, I want to create a new image with a transparent background. On the net, I found many answers which say that I juste need to create a bufferedImage with a specific type as ARGB (type_int_ARGB). But when I use this way, I've got an image with a white background. Why Does it come from my JPanel ( I use the paintComponent() method) Please, someone helps me !! [Message sent by forum member 'karys' (karys)] http://forums.java.net/jive/thread.jspa?messageID=300126 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Drawing an animated gif on a bufferedImage
You can try, but it will only draw the current frame of the GIF to the BufferedImage. BufferedImage objects are just static buckets of pixels so they can't animate. The last parameter to the drawImage call is an optional reference to an ImageObserver that will be notified if/when a new frame in the source image is ready to be painted (it is then up to you to paint the new frame wherever you want it using another call to drawImage() - the notification callback just tells you that it is ready). These callbacks will happen asynchronously based on the thread that is decoding the GIF image. Component implements ImageObserver, but it has a very basic implementation that just repaints the entire component (with a delay for batching) whenever there is any new data ready to be rendered. You probably want to provide your own custom implementation of ImageObserver (it's only 1 method call to implement) that does something more intelligent about updating your BufferedImage instance when it gets a FRAMEBITS or ALLBITS notification... ...jim [EMAIL PROTECTED] wrote: Hi !!! I've another question !! Is it possible to draw an animated gif on a bufferedImage ? I've tried : Image im = new ImageIcon(test.gif).getImage() ; // test.gif is an animated gif ... BufferedImage bi = new BufferedImage(im.getWidth(null), im.getHeigth(null), BufferedImage.type_int_ARGB); Graphics g = bi.getGraphicss(); g.drawImage(im, 0,0,null); g.dispose(); ... // method from JPanel public void paintComponent(Graphics g) { g.drawImage(bi, 0,0, null); } It doesn't seem to work :( [Message sent by forum member 'karys' (karys)] http://forums.java.net/jive/thread.jspa?messageID=300130 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Scaling using java.awt.Image is vay faster than bufferedImage. But Why?
There appears to be a bug in your method. Was this a cut-and-paste error? [EMAIL PROTECTED] wrote: Hi. I am writing an Applet for viewing large (~2600x3500) tiff files. Here is my scaling method public static BufferedImage getScaledInstance( Image img, int targetWidth, int targetHeight, Object hint, boolean higherQuality ) { [...lines deleted for brevity...] ret = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = ret.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); g2.drawImage(img, 0, 0, w, h, null); g2.dispose(); This line should be added here: img = ret; } while (w != targetWidth || h != targetHeight); [...more lines deleted for brevity...] } Does that help the timings any? It should definitely improve the quality of the results for this case. Also, which version of the JDK are you using and what kind of image is returned from the ImageIO.read method? Doing a System.out.println() on the returned BufferedImage will print out a lot of detail about its type and internal storage structure. Also, if you run with the command line argument -Dsun.java2d.trace=log you can see which kinds of operations are used for the scaling operations. ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Basic issues with affine transforms
[EMAIL PROTECTED] wrote: If I draw a rectangle in the center of a panel at say (x, y) and then I draw it again after appying a scale of (sx, sy), how do I get it so that the center of the rectangle at both scale levels is in the same location on the screen, i.e. (x, y)? It looks like I need to apply a translate transform (dx, dy) as well but what would the dx and dy be in this case? The typical way to change the point around which transforms are applied (like rotate and scale typically) is to use the following paradigm: If you want to scale and/or rotate a figure around ox,oy then use: translate(ox, oy); // rotate(theta); // scale(sx, sy); translate(-ox, -oy); In your case ox,oy == x,y so just use those coordinates and you should be fine. Also, is there some way to determine the *scaled* attributes of the rectangle after the scale has been applied? Obviously rect.x and rect.width are not going to change so what I want is the actual location of the rectangle's x and the actual width of the rectangle as it appears on the screen after the scaling has been applied. For a simple transformation like scaling you could just use: AffineTransform at = new AffineTransform(); at.translate(x, y); at.scale(sx, sy); at.translate(-x, -y); double coords[] = {rx, ry, rx+rw, ry+rh}; at.transform(coords, 0, coords, 0, 2); scaled rx,ry are in coords[0], coords[1] scaled rw,rh are calculated as coords[2] - coords[0], coords[3] - coords[1] For a more general transform involving flips, rotations, or shears, then it is not quite so simple as the rectangle will be upside down or backwards or a general diamond shape... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Basic issues with affine transforms
Choose the coordinate that you want to remain constant and use that coordinate in the first and last translates. If 100,100 is the coordinate that you want to not move during the transform, then use that coordinate. If there is some other coordinate that you want to remain unchanged then use that coordinate instead - it is totally under your control. In other words, the paradigm is: constantx = the coordinate I want to remain fixed constanty = the coordinate I want to remain fixed translate(constantx, constanty); // do some rotates, scales and shears translate(-constantx, -constanty); And all coordinates other than constantx, constanty will move relative to them but those coordinates will remain firmly fixed on the screen... ...jim [EMAIL PROTECTED] wrote: Hi Jim, Thanks very much for the info. While I can understand the second tip, the first tip doesn't seem to yield exactly what I am after so perhaps my explanation was poor. I want to draw a rectangle at say (100, 100) with no transforms applied and then draw it again with a scale factor of (2, 2) for example but have it so that both rectangles share the same central point (100, 100). Think of concentric circles only with rectangles. Your example (at least the way I tried it) seems to align the two rectangles so that the point (100, 100) sits on one of the corners of each rectangle so that they are around the point but do not have it at their center. Does this make sense? === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] drawImage() and isAlphaPremultiplied()
Hi Charles, This is really a question for JAI since I believe they own the TIFF writer. I forwarded your question on to Brian Burkhalter for more information. He may draw the question off onto a JAI list as well. Either way you should hear from him... ...jim [EMAIL PROTECTED] wrote: Hi Jim, I also have a question related to the coerceData() method. It may be out of place here, just let me know. I've tried other forums (see below) with limited success. It has to do with writing a BufferedImage out as a TIFF format file (using the class com.sun.media.jai.codec.TIFFEncodeParam). In the JAI forum I was advised to use the coerceData(true) in order to guarantee that the alpha channel of the image would be written out as assoc alpha rather than unassoc alpha -- in the latter case most image packages won't recognize it as the transparency channel, hence making the TIFF file not very useful. But I've noticed that coerceData(true) seems to have the sort of unintended consequences referred to in your post, making the saved files also useless. So, my question: is there another known way to make sure the TIFF file gets written out with the assoc alpha flag turned out, short of calling coerceData(true)? Simply allocating an image of type TYPE_INT_ARGB_PRE doesn't seem to do so. It appears that I can save the images as PNG files and get the alpha channel saved as transparency information, so I can live without this, but the TIFF format has certain advantages that I'm reluctant to forgo. (This topic may be too far afield from this discussion, please let me know.) Charles [Message sent by forum member 'charlesgunn' (charlesgunn)] http://forums.java.net/jive/thread.jspa?messageID=296668 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Copying a portion of an Image?
It depends on your definition of the term from the contents of. The simplest way to get a snapshot of a subrectangle of an existing image is to simply create a new image and draw the original into the new one, as in: // assuming: Image src; int subx, suby, subw, subh; // then execute: BufferedImage snap = new BufferedImage(subw, subh, TYPE_INT_RGB); Graphics2D g2d = snap.createImage(); g2d.drawImage(src, -subx, -suby, null); g2d.dispose(); // snap is now a snapshot of subx,y,w,h of src and the snap image will now be a snapshot of the contents in that rectangle (subxywh) of the original src image, and it will be a BufferedImage as you requested. Further rendering on the src image will not affect the contents of the view image and vice versa. If you didn't want a snapshot, I can outline other ways, but I'm guessing that this is probably what you wanted...? ...jim [EMAIL PROTECTED] wrote: I feel fairly stupid asking this question, as it seems like an operation that should be pretty simple, and it probably is, but for whatever reason I can't figure out the best way to do it. So I'm sorry in advance. :-) I'd like to create a new BufferedImage from the contents of a subregion of an existing java.awt.Image. What is the best, least bloated, least convoluted way to do this? Thanks in advance, Laird [Message sent by forum member 'ljnelson' (ljnelson)] http://forums.java.net/jive/thread.jspa?messageID=295189 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Copying a portion of an Image?
Yes, if you want alpha you should pass in TYPE_INT_ARGB. Note that the default compositing mode of the freshly retrieved graphics object is SRC_OVER. The code sample still works fine since the newly constructed image is all 0's (transparent pixels) so copying your source image over the fully transparent image works just fine. But, if you try to reuse the image and copy a different section of the source image into it at a later stage then you might want to do the image copy using g2d.setComposite(AlphaComposite.SRC)... ...jim [EMAIL PROTECTED] wrote: // assuming: Image src; int subx, suby, subw, subh; // then execute: BufferedImage snap = new BufferedImage(subw, subh, TYPE_INT_RGB); Graphics2D g2d = snap.createImage(); g2d.drawImage(src, -subx, -suby, null); g2d.dispose(); // snap is now a snapshot of subx,y,w,h of src OK; thanks. If you didn't want a snapshot, I can outline other ways, but I'm guessing that this is probably what you wanted...? Yep. What allowed you to know that TYPE_INT_RGB was the correct parameter to pass in the BufferedImage constructor? If it helps, I know that the source image often has an alpha value set. Would I use TYPE_INT_RGBA in this case? Thanks again for helping this newbie out. Best, Laird [Message sent by forum member 'ljnelson' (ljnelson)] http://forums.java.net/jive/thread.jspa?messageID=295232 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] drawImage() and isAlphaPremultiplied()
Hi Michael, I think you are getting confused by some under-documented APIs that never had a useful purpose for developers and, in consequence, that have some undiscovered bugs in them. coerceData is not the way to make a premultiplied image. Even worse, it can have dangerous effects on an existing image. It is used internally to munge raster data in the constructor that takes a raw raster and colormodel, but it is not meant to be used in any other cases, or its behavior in other cases is questionable at best, and buggy as you've discovered at worst. If you want a premultiplied raster, then use the TYPE_INT_ARGB_PRE image type, don't use coerceData. The dangerous thing that coerceData is doing is that it is replacing the ColorModel in the image with a new one that doesn't match its declared type. When we go to render into/out of it we end up believing its type and we do the wrong thing. Unfortunately, I'm not sure how to deal with that bug in the coerceData method now - a BufferedImage is not supposed to ever change its type, but this method can cause it to change its nature. I believe the right thing for us to do is to gut the method and deprecate it and move the functionality of what it currently does into the custom constructor. In any case, simply create your images using TYPE_INT_ARGB (for non-premultiplied) and TYPE_INT_ARGB_PRE (for premultiplied) and you should be good to go... ...jim [EMAIL PROTECTED] wrote: When copying an image using Graphics2D.drawImage(),I'm suprised to find that the isAlphaPremultiplied() property of the two images is not taken into account. I believe the pixels are copied directly without respect to color model. A little example is below. I would expect the normalized (sRGB) pixel for each image to be the same, but instead the real pixel value is the same and the interpretation and normalized data differ. Is this a bug or am I misunderstanding how these things should work? Thanks much, michael [code] public static void main(String[] args) { BufferedImage premultiplied = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB); BufferedImage notpremultiplied = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB); premultiplied.coerceData(true); notpremultiplied.coerceData(false); Graphics2D preG = premultiplied.createGraphics(); preG.setColor(new Color(0, 40, 0, 120)); preG.fillRect(0, 0, 10, 10); preG.dispose(); // prints: // real: pixel:2013276160 120,0,85,0 // normalized: pixel:2013287680 120,0,85,0 printOriginPixel(premultiplied); Graphics2D notG = notpremultiplied.createGraphics(); notG.drawImage(premultiplied, 0, 0, 10, 10, null); notG.dispose(); // prints: // real: pixel:2013276160 120,0,40,0 // normalized: pixel:2013276160 120,0,40,0 printOriginPixel(notpremultiplied); } public static void printOriginPixel(BufferedImage image) { int defaultColorSpacePixel = image.getRGB(0, 0); int realPixel = ((int[]) image.getRaster().getDataElements(0, 0, null))[0]; System.out.println(real: pixel:+ realPixel + + image.getColorModel().getAlpha(realPixel) + , + image.getColorModel().getRed(realPixel) + , + image.getColorModel().getGreen(realPixel) + , + image.getColorModel().getBlue(realPixel)); System.out.println(normalized: pixel: + defaultColorSpacePixel + + ColorModel.getRGBdefault().getAlpha(defaultColorSpacePixel) + , + ColorModel.getRGBdefault().getRed(defaultColorSpacePixel) + , + ColorModel.getRGBdefault().getGreen(defaultColorSpacePixel) + , + ColorModel.getRGBdefault().getBlue(defaultColorSpacePixel)); } [/code] [Message sent by forum member 'kazoobrewer' (kazoobrewer)] http://forums.java.net/jive/thread.jspa?messageID=293378 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] How to backup the contents of a volatileImage
Just to be clear, you are calling g.drawImage(img, width, height, null) in the pseudo-code below which draws img at the location w,h - don't you want to draw it at (0,0) as in: g.drawImage(img, 0, 0, null); or was that a typo in the pseudo-code? ...jim [EMAIL PROTECTED] wrote: Hi, I am currently rebuilding quite an old graphics library from software rendered Images to hardware accelerated VolatileImages. I am nearly done with this task, but now I have encountered an old functionality that requies the backup of the Image-content in order to do a scrolling of the zoomed selection over the original scaled graphic. In the old version it was quite easy to do. They just made a new Image object, and assigned the to be saved image to it: Image copy = new Image(width, height); copy = originalImage; stack.push(copy); After the assignment, they put the copy on an Object stack, where (inscrolling mode) they can recall this image. How can I achive tha same functionality when originalImage is of the type VolatileImage? I am pretty sure, that I can't put a volatile image in our stack, as the contents could be lost on th stack without beeing recognized. So my approach was to draw the contents of the volatile image onto an Image-typed object: Image copy; copy.getGraphics.drawImage(originalImage, originalImage.getWidth(), originalImage.getHeight(), null); stack.push(copy); In the case of recalling the backup, I do the same things the other way around: originalImage = this.getGraphicsConfiguration.createCompatibleVolatileImage(copy.getWidth(), copy.getHeight()); originalImage.getGraphics.drawImage(copy, copy.getWidth(), copy.getHeight(), null); Unfortunatly, it does not work as I expected because originalImage does contain after these lines above still the same content as if I never called these lines and not the content I saved earlier in the copy image. Question: Is this approach appropriate for that what I intend to do? Thanks, Maik [Message sent by forum member 'kiamur' (kiamur)] http://forums.java.net/jive/thread.jspa?messageID=293223 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] line2D length problem
Hi Lew, You are describing the default behavior which assumes CAP_SQUARE. The line itself is infinitely thin and goes from one coordinate to the next, don't think of pixels. So, 20,60 to 20,60 goes nowhere - it has a length of 0. 20,60 to 21,60 goes a total distance of 1 unit and has a length of 1. Now with CAP_SQUARE, the first line is extended by lw/2 off the front and back so it extends a total of lw in the direction of the line (ignore for now that a 0-length line has no direction), and obviously it extends lw perpendicular to the line (and centered on the line). If lw=1 then it is a 1x1 square - but only with CAP_SQUARE. Also with CAP_SQUARE, the second line is extended by the same lw/2 off both ends, and so it is 1 unit long and extends another lw units so it is a total of lw+1 long or 2 units long for a lw=1 line. It extends lw perpendicular as well so it is a 2x1 line. With CAP_BUTT, there are no extensions so the 0-length line is only 0 units long and the 1-length line is only 1 units long... ...jim [EMAIL PROTECTED] wrote: Thanks Jim, After all the time I've spent on this it seems I still do not full understand it! Everything I have read on this seems to confirms my thinking, it just doesn't translate when using line widths 1. My understanding is (or was) that the arguments to the Line2D methods , as either x,y coordinates or Points set the endpoints of the line. If I draw a line (with line width of 1) from coordinates 20,60 to 20,60 it would cover 1 pixel below and to the right of the coordinate which would be the pixel 20,60 (current user space). So as 20,60 21,60 are two distinct coordinate points , if I draw a line using these coordinates as the endpoints, I expected to get a 2 pixel line length (and did with line width of 1). Similarly if i set 2 Points to the coordinates above and use .. setLine(Point2D p1, Point2D p2) it would cover 2 pixels. ( and does with line width of 1 but not with a width 1 From the Sun APi Class Line2D docs .. setLine(Point2D p1, Point2D p2)Sets the location of the end points of this Line2D to the specified Point2D coordinates. Without wishing to take the discussion away from the points above, the end cap options raise another issue.. If I had set CAP_SQUARE or ROUND with a line width of 1, where would it decide to add the additional pixel? Normally half the line width and adding it to each end point? I guess this issue happens any time the line width is an odd pixel number. Lew [Message sent by forum member 'aussielew' (aussielew)] http://forums.java.net/jive/thread.jspa?messageID=292007 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] line2D length problem
Hi Lew, A line from 20 to 21 should only be one pixel long as the distance between those points is only 1 pixel. The bug is that we drew 2 pixels when you gave us the first stroke. I think I know what's causing that. We have a test to see if the line width is small enough to generate single pixel wide lines and then we just use bresenham. I don't have the code in front of me, but I'm 99% sure that we don't check the CAP setting when we classify the lines as thin and so we don't note that we should leave off a pixel and just use the default bresenham which models something similar to a CAP_SQUARE or CAP_ROUND type of a line length... :-( ...jim [EMAIL PROTECTED] wrote: Hi All, Hoping someone can help me with this one ...? I need to draw lines with a width greater than 1 and the lengths may be a real value so I am using Line2D.Float. I need to draw exact (calculated)lengths so I am using CAP_BUTT so the line does not have any additional apparent length (the other CAP options have the effect of adding the line width to the line) The problem I am having is that once the line width is set to greater than 1, the lines are actually drawn 1 pixel short. I am sure I am missing soething simple here but have spent a lot of time on it! I know that I can work around it but do I need to, I shouldn't have to + 1 to my line lengths depending on there width? The following demonstrates the problem. I am drawing on a JPanel within a JFrame, JDK/JRE 6, Windows g2.setStroke(new BasicStroke(1,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL)); g2.setColor(Color.BLACK); g2.draw(new Line2D.Float(20,40,20,75)); // vertical line as marker only // draw 2 lines with line width of 1 g2.setColor(Color.RED); g2.draw(new Line2D.Float(20,60,21,60)); // draws 2 pixel line as expected g2.draw(new Line2D.Float(22,60,23,60)); // draws 2 pixel line as expected ... total of 4 pixels // draw 2 lines with line width of 10 g2.setStroke(new BasicStroke(10,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL)); g2.setColor(Color.GREEN); g2.draw(new Line2D.Float(20,70,21,70)); // draws 1 pixel only at 20,70 g2.setColor(Color.YELLOW); g2.draw(new Line2D.Float(22,70,23,70)); // draws 1 pixel only at 22,70... so, each line is shortened by 1 pixel // this applies to any line width 1 Thanks Lew [Message sent by forum member 'aussielew' (aussielew)] http://forums.java.net/jive/thread.jspa?messageID=291753 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Universal image reading
Hi Adam, I haven't read through everything you've written here, but it sounds like you've already learned about the major players here - there are access methods at a number of levels - BufferedImage, Raster, DataBuffer, and some helper methods on SampleModel and ColorModel as well. The further down you dig, the faster things run since you are closer to the metal. [Keep in mind that digging the DataBuffer out of a Raster will defeat the managed image acceleration of BufferedImages in 1.6 and earlier - 1.7 will have a more flexible accounting scheme that lets you get the DataBuffer from a BufferedImage as long as you don't call the getData() method on the DataBuffer to get the raw Java array.] Note that the simplest, easiest to use, jack of all trades, accessor would be BufferedImage.getRGB(x, y) which returns a 32-bit ARGB value regardless of the underlying image type. It won't be as fast as analyzing the image and using the underlying methods that you've already investigated, but it lets you get the job done if you fall through the cracks of your image type detection code and it performs well enough for smaller tasks - grabbing the value of the occasional pixel... ...jim Adam Augusta wrote: So I've written a limited Java EPS creator for image files using BufferedImage and Image I/O, but it's not perfect. I need to determine if it's RGB, CMYK, or grayscale (including 1-bit BW), get the bits per component, collect the samples in per-pixel sequence in a certain order (RGB not BGR), and write my EPS. Oh, and if there's an alpha channel, I need to get those values and handle them specially. Ascertaining type: BufferedImage#getColorModel#getColorSpace#getType works for CMYK, but for 1-bit BW, it reports 8-bit RGB. BufferedImage#getType works for 1-bit BW (BufferedImage.TYPE_BYTE_BINARY), but not for CMYK (BufferedImage.TYPE_CUSTOM). So already, I'm forced to use a different strategy for different kinds of images. Do I have the right idea? Accessing sample information with a ColorModel is easy. final Object reusableDataArray = raster.getDataElements(x, y, null) final int[] reusableSampleArray = colorModel.getComponents(sampleArray, null, 0); final int bitsPerComponent = colorModel.getComponentSize(0); Accessing sample information from a Raster/SampleModel (TYPE_BYTE_BINARY) isn't quite so easy. BufferedImage#getType provides enough information to interpret the output of Raster#getPixel, but that means I have to write new logic for each #getType. So right now, through trial and error I'm typing up a list of BufferedImage.TYPE_*s that work well with ColorModel, and handling them consistently. For each types that don't work well with ColorModel, I'm writing special logic to interpret Raster#getPixel. Am I on the right track, or am I just making this hard for myself? === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Any way to make ANTIALIAS only use one color
You shouldn't be using Antialiased rendering on an Indexed image. Antialiasing requires the ability to choose a color that is N% of the way from the foreground to the background and store that color, but that color may not be in the colormap of an Indexed image. One could argue that we should have just ignored the AA hint for Indexed images since we may not find the intermediate colors that we need for the effect, but some images may actually have enough of the intermediate colors that we can render a nice effect even just restricting ourselves to the colors available in the colormap. So, we left it in and let the developer choose whether or not it is working well for their situation (which depends on the colormap that they are using). Since it doesn't seem to be working well with your particular colormap, my suggestion is to not use Antialiasing - or to come up with a better selection of colors in your colormap that provide enough intermediate colors for the AA algorithm to do its job... ...jim [EMAIL PROTECTED] wrote: If I draw into an Indexed bitmap, it seems that with antialias on it uses some kind of change color on edges algorithm. I am writing with one color, but the new pixels that antialiasing adds are not always the same color. I need to find a way to turn this off, and force it to use the same color. [Message sent by forum member 'keith198' (keith198)] http://forums.java.net/jive/thread.jspa?messageID=290418 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] creating a BufferedImage and efficient way of reusing.....
How are you taking the snap shot? How do you receive that snapshot into Java? By loading it as an image, or are you using the built-in robot facilities to do the snapshot? If you are using robot, then the image will already be a BufferedImage so you don't need to convert it. If you are loading a snapshot stored as a file, then you can load the image using ImageI/O instead of Toolkit/Component.getImage() and get a BufferedImage that way... ...jim [EMAIL PROTECTED] wrote: First, i am extracting images from the video stream by taking a snap shot of each images from the video, and then I extracted the pixels data from those images using pixelGrabbers. This return a byte[] array of pixels information of the image. then i create BufferedImage using the method i posted above, but the way that i have written can cause out of heap memory error because i am declaring new everytime i got a new dataBuffer. the dimension of the byte[] dataBuffer is the same; the only change is the pixel info. Here is some part of my program: public class ExtractImage{ //start video stream //then take a snap shot of video at every 5 seconds. //then extract the pixel info from the snap shot image using pixelsGrabber, and //then put that data in the byte[] dataBuffer array. //After that produce BufferedImage or RenderedImage by calling this //produceRenderedImage method. public BufferedImage produceRenderedImage(byte[] dataBuffer, int width, int height) { DataBuffer dBuffer = new DataBufferByte(dataBuffer, width * height); WritableRaster wr = Raster.createInterleavedRaster(dBuffer,width,height,width,1,new int[]{0},null); ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); ColorModel cm = new ComponentColorModel(cs,false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); BufferedImage bi = new BufferedImage(cm, wr, false, null); return bi; } } thanks for all your help. i really appreciated it. Francis [Message sent by forum member 'cohodetector' (cohodetector)] http://forums.java.net/jive/thread.jspa?messageID=289444 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Taking advantage of printer's native resolution
A line width of 0 should produce the thinnest line representable on the device. If the line disappears then that is a bug... ...jim [EMAIL PROTECTED] wrote: Since I have not received an answer to my previous question, I will try to simplify it even further. For an arbitrary printer, how can I print a single line that is one printer dot wide by N dots long, ie, print the finest line the printer is capable of printing? For a 300dpi printer this line would be a line 1/300 wide. For a 2400dpi printer this would be a line 1/2400 wide, etc. Thanks! [Message sent by forum member 'robross' (robross)] http://forums.java.net/jive/thread.jspa?messageID=287172 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] What is the fastest way to draw a small portion of a BufferedImage?
That should be the best way. It is independent of what kind of image you are using... ...jim Ken Warner wrote: I need to draw just a small rectangular portion of a BufferedImage. What is the absolute best, fastest way to do that? Is their a tutorial that will show how to do that. Note that this is a different task than before. There will be no projection done on that rectangular part of the BI. It will be just a straight draw to the screen. For example: Let's say I have a 1000 x 1000 pixel image and I just want to draw the portion starting at x = 200, y = 200, width = 100, height = 100 Is using public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) the best way or is there another best way in the ...new imaging API... === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] I need a way to decode an image file directly into a byte or integer array...
When I run the applets from appletviewer I see 16 numbers printed on the console for the BI version but only 8 printed for the PG version - hopefully there isn't a typo causing the loads to be done twice? ...jim Ken Warner wrote: Hi Jim, I'm not communicating the step by step procedure for the projection I guess. It's not like you describe. There is no massaged data. It's just a pixel map that I take a portion of and calculate a gnomic projection. If I had a white board I could draw a diagram that explains everything. It's a realtime (sort of) projection. Anyway, here's the two different versions of the applet I promised. One uses PixelGrabber the other uses BufferedImage. This is the performace problem I'm seeing. I always take the blame for something like this until proven otherwise. So I must be doing something wrong but the code is so simple I just don't see where. http://pancyl.com/BufferedImage.htm http://pancyl.com/PixelGrabber.htm PixelGrabber works ok for a prototype. BufferedImage is a mystery yet. You have the source to the class where the problem is. If you have time to take a look at makeBuffereImage() and maybe you will see something I don't. Ken Jim Graham wrote: Hi Ken, Do you really need to rewrite it all the way through? For example, the massaged data (that has been run through the panoramic projection) could be stored in integer format - it's just the code that reads a pixel out of the source tiles that needs to change, but any intermediate storage and the final storage that you use could be integer-based. I'd have to see the conversion code to make any suggestions beyond these guesses... ...jim Ken Warner wrote: I'll try that. Using bi = reader.read(0,param); PanTile Testbed 1813 1031 1001 982 941 981 1002 971 Using bi = reader.read(0) -default reader PanTile Testbed 1081 601 291 330 261 270 300 280 Using PixelGrabber etc. PanTile Testbed 1432 1221 1272 1112 1141 1081 1101 1092 Clearly the default reader is faster by a lot -- except the data is not in a format I can use in the current version. The current version of the apple is only expected to download one image so I wasn't much concerned with that piece of code. A version loading tiles is another thing. But the code would have to be re-written all the way through to the final paint loop. Because I use integer arrays everywhere. Maybe it would be worth the effort if I could be sure that the final performance was really going to be much faster than it is now. The rendering would have to be significantly faster to make the re-write really worth the effort. And while I have been resistent to the idea of using BufferedImages -- I will do anything to make my applet faster. But given that the applet is stable and fairly well tuned using integer arrays, I'm not likely to re-write it using the three byte databuffer to save 800ms per 1meg tile. Tiles will most likely be even smaller. *And the performance slowdown is after I get the pixels from the databuffer.* After the int [] pixels is assigned to, all the other code remains the same except I see this unexplained slow down in user interaction. If I can figure that problem out (with your help) then it might be worth the re-write. [stuff deleted] === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] I need a way to decode an image file directly into a byte or integer array...
The 3byte databuffer has no storage available for an alpha value. When the data is loaded into the TYPE_INT_RGB BufferedImage there is no alpha stored there since that is an opaque type. More specifically, if you load one of the integers from the underlying int[] pixel array of such an image the upper 8 bits are undefined and should be ignored - if those bits are 0 then that does not mean that the pixel is transparent, and if they contain a 0xff value then that is just a lucky coincidence as those bits are not explicitly tracked or initialized by any code that deals with that image type... ...jim Ken Warner wrote: I just thought of something. What is the alpha channel set to when the BufferedImage is created and the databuffer is extracted? If the alpha channel is 0, that would explain a lot. That means the image is transparent. There's two stages of rendering. The first stage only does nearest neighbor interpolation. The second stage does a bi-cubic interpolation and I explicitly initialize the alpha channel to 0xff to make the image not transparent. Ken Warner wrote: Hi Jim, I'm not communicating the step by step procedure for the projection I guess. It's not like you describe. There is no massaged data. It's just a pixel map that I take a portion of and calculate a gnomic projection. If I had a white board I could draw a diagram that explains everything. It's a realtime (sort of) projection. Anyway, here's the two different versions of the applet I promised. One uses PixelGrabber the other uses BufferedImage. This is the performace problem I'm seeing. I always take the blame for something like this until proven otherwise. So I must be doing something wrong but the code is so simple I just don't see where. http://pancyl.com/BufferedImage.htm http://pancyl.com/PixelGrabber.htm PixelGrabber works ok for a prototype. BufferedImage is a mystery yet. You have the source to the class where the problem is. If you have time to take a look at makeBuffereImage() and maybe you will see something I don't. Ken Jim Graham wrote: Hi Ken, Do you really need to rewrite it all the way through? For example, the massaged data (that has been run through the panoramic projection) could be stored in integer format - it's just the code that reads a pixel out of the source tiles that needs to change, but any intermediate storage and the final storage that you use could be integer-based. I'd have to see the conversion code to make any suggestions beyond these guesses... ...jim Ken Warner wrote: I'll try that. Using bi = reader.read(0,param); PanTile Testbed 1813 1031 1001 982 941 981 1002 971 Using bi = reader.read(0) -default reader PanTile Testbed 1081 601 291 330 261 270 300 280 Using PixelGrabber etc. PanTile Testbed 1432 1221 1272 1112 1141 1081 1101 1092 Clearly the default reader is faster by a lot -- except the data is not in a format I can use in the current version. The current version of the apple is only expected to download one image so I wasn't much concerned with that piece of code. A version loading tiles is another thing. But the code would have to be re-written all the way through to the final paint loop. Because I use integer arrays everywhere. Maybe it would be worth the effort if I could be sure that the final performance was really going to be much faster than it is now. The rendering would have to be significantly faster to make the re-write really worth the effort. And while I have been resistent to the idea of using BufferedImages -- I will do anything to make my applet faster. But given that the applet is stable and fairly well tuned using integer arrays, I'm not likely to re-write it using the three byte databuffer to save 800ms per 1meg tile. Tiles will most likely be even smaller. *And the performance slowdown is after I get the pixels from the databuffer.* After the int [] pixels is assigned to, all the other code remains the same except I see this unexplained slow down in user interaction. If I can figure that problem out (with your help) then it might be worth the re-write. [stuff deleted] === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL
Re: [JAVA2D] I need a way to decode an image file directly into a byte or integer array...
Hi Ken, I'm sorry that you are having trouble understanding the newer imaging APIs as they generally provide facilities that are quite flexible and useful for writing the type of application that you are creating here. The primary missing link would seem to be some documentation that would bridge the gap for you and I have been trying to help you out there with some email conversations behind the scenes. Apparently the frustration there is not worth the gains for you. This may not make sense to you, but your request for a new API to produce the data you want would not streamline the process for the simple fact that you want to work with data in a format that differs from what is generated by the JPEG decoders so some format conversion must occur somewhere. The only conversion free way to get the raw pixel data from the JPEG decoders is to accept it in the 3byte format that they want to generate it in. Your request for a new API would not change that fundamental fact of the JPEG format in any way. The old PixelGrabber code was probably the least efficient way to get the data converted into the format you want. The ImageI/O mechanism you chose, which allows you to specify the format of the generated BufferedImage is more efficient than the PixelGrabber method per your own image reading benchmarks. Apparently it had some negative interaction with the rest of the code which I was hoping to help you figure out, but it is hard for me to debug such problems via email without seeing the rest of the code. Adapting your code to the inherent storage format used by the JPEG decoders (the 3byte format) is the only way to eliminate the loading overhead. We aren't being lazy or obstinate here Ken. Just because you can write pseudo-code for your desired API doesn't mean it will magically implement itself with zero overhead. It won't happen. If you do not wish to understand the underlying flow of pixel data enough to understand that, then feel free to live with the overhead of whichever mechanism you find most easy to use. As you pointed out in an earlier email the image decoding step is far from the most important player in your process, so worrying about speeding up the rest of the process would probably be more fruitful in the long run anyway. Good luck! ...jim Ken Warner wrote: Whatever... The image was not being drawn because the alpha channel was 0x00. Initializing the alpha channel to 0xff allowed us to see the image. I don't have a lot of energy for a big discussion about this. But this whole experiment still leads me back to ask for a way to decode an image directly into an integer array like I first asked. Something like pixels = imageReader.decodeFileBytesToIntegerArray(...) But all I seem to get from you is ...rewrite the applet... Ok. I think I'm done. Jim Graham wrote: The MemoryImageSource relies on the ColorModel to define whether or not the data contains an alpha channel. If you use one of the MIS constructors that does not take a ColorModel object then those constructors are specifically specified to use the default RGB ColorModel as defined by the ColorModel.getRGBdefault() method which specifies 8 bits of alpha. I'm not sure what you mean when you say that it means it's transparent to [...] BufferStrategy since that object doesn't deal with pixel storage formats... ...jim Ken Warner wrote: Maybe it doesn't mean the BufferedImage is transparent but 0x00 in the alpha channel of a pixels means it's transparent to the MemoryImageSource and BufferStrategy. Jim Graham wrote: The 3byte databuffer has no storage available for an alpha value. When the data is loaded into the TYPE_INT_RGB BufferedImage there is no alpha stored there since that is an opaque type. More specifically, if you load one of the integers from the underlying int[] pixel array of such an image the upper 8 bits are undefined and should be ignored - if those bits are 0 then that does not mean that the pixel is transparent, and if they contain a 0xff value then that is just a lucky coincidence as those bits are not explicitly tracked or initialized by any code that deals with that image type... ...jim Ken Warner wrote: I just thought of something. What is the alpha channel set to when the BufferedImage is created and the databuffer is extracted? If the alpha channel is 0, that would explain a lot. That means the image is transparent. There's two stages of rendering. The first stage only does nearest neighbor interpolation. The second stage does a bi-cubic interpolation and I explicitly initialize the alpha channel to 0xff to make the image not transparent. Ken Warner wrote: Hi Jim, I'm not communicating the step by step procedure for the projection I guess. It's not like you describe. There is no massaged data. It's just a pixel map that I take a portion of and calculate a gnomic
Re: [JAVA2D] I need a way to decode an image file directly into a byte or integer array...
Hi Ken, ImageI/O reads images into a BufferedImage which provides easy access to a Java int/byte array with the pixels. Details of pixel access for BufferedImage objects were discussed recently on this thread: http://forums.java.net/jive/thread.jspa?messageID=269294 ...jim Ken Warner wrote: I think there is a hole in the greater Java API for working with images. Images and BufferedImages are great if all you want to do is download an image file and put it on the screen. They are really good at that. But if someone (like myself) needs to work at a lower level -- at the pixel level to prepare and synthesize pixels for display, the existing API's are way too complicated. There is no way to read an image file -- jpg, tif, png, whatever -- and simply decode that image file into a byte or integer array. You always have to ask for an image of one sort or another to be created. And that is not a straight forward procedure either. If you use the Toolkit to make your image, you have to make a MediaTracker to wait for the image to be made somewhere deep in the JVM. Then, if you want to manipulate the pixels of the image directly either to change the color or position of a particular pixel or to generate a new set of pixels, you have to either ask the image for the pixel or use a PixelGrabber to ask the image for it's pixels in either byte array or integer array form. If you use a PixelGrabber, again you have to wait for an ImageProducer to deliver the pixels in the array of your choice. And that process has to be carefully minded to make sure it completes. It would be so much simpler if I could just decode an image file directly into a byte or integer array. I'm starting a new project where I will be rendering huge panoramic images sometimes as big as 50,000x25,000 pixels or even bigger. To do that, I will be downloading tiles from the panorama as needed on demand. The image will be made into a manageable set of tiles by other tools. There may even be a set of tiles at different resolutions for the same panorama. So for each tile I have to download the image file, make an image and watch over that process with a MediaTracker and after the Image is made, make a PixelGraber to grab the pixels and watch over that process then when I have (in my code) integer array -- I throw all that stuff away (flush the image resources etc.) and do the whole thing over again for the next tile. Maybe ImageIO Tools has a way to do that but now that's a separate download and install and until the next generation plugin -- which will simplify silent installs of extra packages -- is widely deployed , not an option. I don't know of a way to simply decode an image file into a byte or integer array. I hope that there really is a way and I'm just not aware of it. I don't mind being dumb. I'm dumb a lot. So if anyone knows a way to decode an image file directly into a byte or integer array, please tell me how to do it. Ken === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] I need a way to decode an image file directly into a byte or integer array...
Hi Ken, Sorry to disappoint, but without any feedback as to why the creation of a BufferedImage is a problem we are not likely to create an API like this. The existing APIs are designed for maximum usefulness to the most developers. Your requirement can be derived from the existing APIs using only about 3 or 4 lines of code. I don't see the need to add more methods to the API here. For what it's worth, I would stay away from the Toolkit Images and the MediaTracker and PixelGrabber mechanisms for your needs here. They add a huge amount of overhead to the process you are using. ImageI/O does almost exactly what you need with much less overhead... ...jim Ken Warner wrote: Something is getting lost in the translation -- When I say directly I mean directly from the file bytes into a byte or integer array without first making an Image or a BufferedImage. *Something* like this (and I know it doesn't exist so don't get excited) int [] pixels = Toolkit.createPixelArray(fileBytes,...); Something like that. Notice that I don't make an Image or BufferedImage first. That's what I think would be a useful addition to the greater image handling api. Now to all those who are gnashing your teeth about why I don't want to use BufferedImages -- take a valium and have a beer and a ciggy -- relax and let me live in my own little world without BufferedImages. Jim Graham wrote: Hi Ken, ImageI/O reads images into a BufferedImage which provides easy access to a Java int/byte array with the pixels. Details of pixel access for BufferedImage objects were discussed recently on this thread: http://forums.java.net/jive/thread.jspa?messageID=269294 ...jim Ken Warner wrote: I think there is a hole in the greater Java API for working with images. Images and BufferedImages are great if all you want to do is download [stuff deleted] === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?
[EMAIL PROTECTED] wrote: True - but thats an array. Depending on the internal representation of DataBuffer (which I have not looked into yet), this could mean that the casting has to be done for each element of the array. Once you grab the Java array, you are done grabbing it and done casting. If the image has only one bank (like TYPE_INT_*) then you only need to grab one array. setRGB() on the other hand, which is just a convenience API for setting a few pixels (or even setting all of the pixels if the performance hit isn't in a critical area) has to start from scratch on each operation and must work on all BufferedImage types so it necessarily has to use a lot of more general APIs and perform a lot of duplicate work on every call. If the image format is known, then more direct procedures (like grabbing the Java array) are available, but you have to pack your own pixels if you do so. The fact that using setRGB() for individual pixels costs so much memory, could suggest that the internal raster is not int[]. If it would be that way, this would mean that setRGB() needs to do do a lot of casting and create temporaray objects, which would be a good explanation for the noticed memory consumption. Since I am no expert here, I can only guess. setRGB() consumes memory because it makes no assumptions about any internal storage because it has to work even on a custom constructed BufferedImage with a 3rd party SampleModel and a 3rd party ColorModel and a 3rd party DataBuffer (and a 3rd party ColorSpace as well). For all it knows the colors are represented by calculating the Nth number in the Fibonacci sequence, composing a pixel by distributing its bits using a reversible scrambling algorithm, and finally storing them into an SQL database on another continent. (Perhaps if it took the time to examine the data structures actually being used it might be able to discern a more direct route than using the general APIs on ColorModel, SampleModel and DataBuffer, but it is only available for convenience, not performance.) The primary consumption of memory for setRGB() has nothing to do with whether or not the internal raster is int[], but the fact that many of the general APIs on ColorModel, SampleModel and DataBuffer take small arrays of size 3 or 4 containing one color component per entry in the array - so each call to setRGB() involves the creation of at least one, possibly 2 of these tiny arrays. With the modern garbage collectors in Hotspot, they are geared to be forgiving of a lot of small objects that are used quickly and discarded. MfG; ChaosE [Message sent by forum member 'chaose71' (chaose71)] I think one of the problems is that we never really documented the internal representation of the standard BufferedImage types very well. On one hand, this is for a good reason which I'll get into further below, and on the other hand, this lack of documentation causes them to be scary for the casual user even though they are quite simple. Basically, if you create a TYPE_INT_RGB, or TYPE_INT_ARGB, then it will have 1 Raster with 1 DataBuffer with 1 array of int[] that is large enough for every pixel in the image. You can verify this by examining the SampleModel that it uses and the number of banks in the DataBuffer, etc., but that is the way it will (appear?) to store the internal data. Thus, if you create a BufferedImage of one of those types then you can grab its int[] array once using a code snippet similar to what has already been posted here and keep using it for the life of the image for any pixel in the image - one grab of the array and one cast and then you are done for the life of the image. Now, the good reason why we wanted to be a bit vague on this (even though it is information that is implied by all of the data structures that are composed into the BufferedImage) is that, for example, we wanted the flexibility to not use a Java array for a BufferedImage and put the data into the C heap memory, or into VRAM. Apple has done such an optimization for performance on some of their older runtimes (before we created the managed image facilities which give most of the benefit of that technique without ditching the Java arrays), but that optimization was not a problem for the Java developer because their runtime would automagically promote the image to use a real Java array if you ever called the getData() method on the DataBuffer. In other words, the shift in the underlying storage was transparent to the developer. Thus, optimized storage until you needed then Java array and then first class Java array convenience when you needed it. Also, any benefit of using cached copies or an alternate storage methodology is lost if you are modifying every pixel on every frame (which is what these animation situations tend to do) anyway since one way or another the pixels have to cross the RAM/VRAM boundary and the performance of moving
Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?
Just a small correction... [EMAIL PROTECTED] wrote: Can you try to modify my example code using your suggestion, so that we can see if it produces similiar memory leaking behavior or if it solves it? Sorry, no ... I don't have the time. I post a snippit which should be easy to use: [code] image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); int[] buffer = ((DataBufferInt) img.getRaster().getDataBuffer()) .getData(); [/code] buffer is now width*height in lenght. so width-1 is the first element of the second line. The first element of the first line would be at index 0. The last element of the first line would be at index width-1. The first element of the second line would actually be at index width (not width-1 ;-). But, these rules of thumb make an assumption about the scan stride being used and the offset to the first pixel. Those assumptions will be true for a brand new BufferedImage and on the reference runtime, but there are 2 cases where those assumptions may fail if you care about these situations: - If Java is ever ported to an architecture where alignment stricter than 4-bytes for image data is desired, then the scanline stride may need to be padded to the next 8 (or 16 or ?) byte boundary. - If you want to work on an sub-image, such as those created by the BufferedImage.getSubimage() call then the scanline stride may be totally unrelated to the width of this image, and the offset to the first pixel may not be 0 any more either (since the sub-image is talking to a subset of the image data for the parent image). - If you want to work on a BufferedImage that someone created using their own Raster, it might still be tagged as TYPE_INT_[A]RGB, even though they didn't honor those restrictions that the BufferedImage constructor would impose and so the offset to the first pixel and the scanline stride may be different. The only restrictions on an image created from a Raster to be classified as TYPE_INT_* are that it use a DirectColorModel, a SinglePixelPackedSampleModel and have a pixel stride of 1. If you want to be just a little bit more technically correct then the following should cover you in the situations that require a different scanline stride: // one-time setup Raster r = img.getRaster(); SinglePixelPackedSampleModel sppsm; int buf[] = ((DataBufferInt) r.getDataBuffer()).getData(); sppsm = ((SinglePixelPackedSampleModel) r.getSampleModel()); int scan = sppsm.getScanlineStride(); // per-pixel access code buf[y * scan + x] = /* data for x,y */ And if you want to work on a subimage, or a manually created BufferedImage, then the following should cover all of these bases with only a couple more lines in the setup code: // one-time setup Raster r = img.getRaster(); SinglePixelPackedSampleModel sppsm; int buf[] = ((DataBufferInt) r.getDataBuffer()).getData(); sppsm = ((SinglePixelPackedSampleModel) r.getSampleModel()); int scan = sppsm.getScanlineStride(); int sampX = r.getSampleModelTranslateX(); int sampY = r.getSampleModelTranslateY(); int off = - (sampY * scan + sampX); // per-pixel access code buf[off + y * scan + x] = /* data for x,y */ ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Poor quality rotated text
Just a suggestion about techniques - make sure you use some sort of interpolation filtering hint when you try to rotate an image like this. The default algorithm NEAREST_NEIGHBOR is the fastest, but you'd get better quality with BILINEAR filtering. I'm not sure that BICUBIC (slower still) would be necessary for this application. http://java.sun.com/javase/6/docs/api/java/awt/RenderingHints.html#KEY_INTERPOLATION Having said that, I wouldn't expect any better quality than rotating the outline (but YMMV), so if you are happy with the current solution of rotating the outline (quality and performance) then I'd say stick with that... ...jim [EMAIL PROTECTED] wrote: I think this is a consequence of trying to position each glyph at the closest point its projection on to the theoretical baseline on a relatively low-res device. Indeed. I get very nicely rendered characters with odd looking positions. printer resolutions. Whilst rotating an image would help the baseline I don't think you'd be happy with the appearance of the glyphs. True. I wrote a little test program and the glyph quality is worse. Overall the effect is a little better, at least to my eyes. I was going to try it with a higher resolution image, but will instead try ... Your best option for quality is likely to get the outline of the text Thanks very much I will try that approach. Mark [Message sent by forum member 'mthornton' (mthornton)] http://forums.java.net/jive/thread.jspa?messageID=262249 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Area.isRectangular() behaves differently on Area's that are equal. A bug?
This is probably due to the fact that the Area class does not optimize the case of 2 rectangular areas which abut each other top and bottom into a single rectangular area, but it does optimize the horizontal case. The isRectangular() method performs a trivial check for a single outline with 4 sides, not a more exhaustive comparison to the area that the various pieces cover. In the case of a shape that wasn't optimized by the calculations it may not notice that the result is square. Also, its definition of rectangular is specific to an axis aligned rectangle so your 45 degree rotated square polygon would not evaluate as rectangular as per the intent of its implementation, though the spec doesn't quite call this out (unless your definition of rectangle assumes axis alignment which may be true of the Rectangle class, but not of the common English term rectangular). We should probably clarify that in the method comments. The equals() method does perform the more exhaustive comparison/tests that notice that the area is equal when you compare it to its bounds rectangle. Obviously this fails for the 45 degree rotated square polygon that you test so the answers in that case are consistent with the above clarification of the definition of isRectangular()... ...jim [EMAIL PROTECTED] wrote: Hi, Under certain conditions I find the following: [code] Area a, b; (a.equals(b) b.equals(a)) != (a.isRectangular b.isRectangular()) [/code] Is this a bug? Or am I missing something? === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Merging sysmem vram
The per-pixel overhead of accessing VRAM would probably be more noticeable than the per-operation overhead of getting the pixels into the pipeline - unless there was a lot of overlap between the sysmem images. With little or no overlap then it might even be faster to blit the component sysmem images rather than a single blit of the framebuffer image - depending on the difference in the number of pixels touched... ...jim [EMAIL PROTECTED] wrote: Yeah well I was being a bit stupid. I wanted to copy all my sysmem images (just plain int[]'s) to the int[] data of one big bufferedimage (the framebuffer). Obviously blitting all those sysmem images individually to vram using a bufferedimage per sysmem image would add more overhead vs one framebuffer blit. But all overlaps between sysmem direct vram blits are lost that way ofcourse... So I guess there's no way around doing one bufferedimage per sysmem image. [Message sent by forum member 'bitshit' (bitshit)] http://forums.java.net/jive/thread.jspa?messageID=253587 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Merging sysmem vram
If VRAM is expensive to store per-pixel then the cost you pay to do the blit(s) is dependent on the number of pixels. If you are writing to the same VRAM pixels over and over because the sysmem images overlap then you pay the cost to access pixels that will later be overwritten. By contrast if you blit all of the sysmem images to a temporary memory buffer then the redundant writes to the same pixels will be only at the cost of system memory access which tends to be much faster - later when you copy the temporary buffer to the screen then you only access each VRAM pixel once so there is no wasted or redundant effort with respect to any overlap. What it comes down to is comparing the number of sysmem pixels written by each method and then comparing the costs of writing to VRAM vs. writing to sysmem. If there is little to no overlap in the sysmem images then the answer is a no-brainer since you will write the same or fewer pixels to blit the sysmem images directly to the VRAM than to blit them to a temporary sysmem buffer. If the total number of pixels in the sysmem images is less than the number of pixels in the temporary buffer, then again the cost of doing the blits directly to VRAM will be less because you have fewer pixels to write (even if there is overlap). If there is overlap and the total number of pixels in the sysmem images is larger than the total number of pixels in the temporary buffer, then it depends on the ratios above as to which will be faster... ...jim [EMAIL PROTECTED] wrote: The per-pixel overhead of accessing VRAM would probably be more noticeable than the per-operation overhead of getting the pixels into the pipeline - unless there was a lot of overlap between the sysmem images. With little or no overlap then it might even be faster to blit the component sysmem images rather than a single blit of the framebuffer image - depending on the difference in the number of pixels touched... How come overlapping sysmem images would descrease performance vs non overlapping sysmem images when doing per image blits? [Message sent by forum member 'bitshit' (bitshit)] http://forums.java.net/jive/thread.jspa?messageID=253855 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Is createContext for TexturePaint broken in OS X
Hi Mark, In an ideal world we would have made TexturePaint, or at least its createContext() method, final. Internally it is useful for us to know that a texture is being applied so we can use optimized code to paint with the texture directly rather than having to call createContext() and cause Raster objects to be created for the data. We used to have cases in our code as well where we would do an instanceof on TexturePaint before we ran across someone trying to subclass it as you are doing. We've since tried to trigger off of comparing the paint.getClass() to TexturePaint.class so we only apply the optimizations in the case where it is a true TexturePaint instance, but that is less than ideal in the long run as the more specific test does not use language optimizations and also penalizes developers who subclass TexturePaint for reasons other than to override the createContext() method. I'm guessing Apply may still have a few instanceof tests in their code. Have you tried it on their beta version of 6 at all? Also, out of curiousity, why are you overriding the createContext() method? ...jim Mark Stephens wrote: We have a custom TexturePaint where we override createContext. This is not working in Apples Java 1.5. It seems that our over-ridden context is never called. Has anyone else seen this behaviour? Is there a work around? Regards, MArk === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Java2D Disposer mechanism
One thing to add... I was tracking down an issue that someone was having internally with using the Disposer and thought that maybe the problem was that they didn't understand how we use the DisposerTarget interface. Strange that their query and your email were separated only by minutes. ;-) It turns out that their problem was unrelated, but in doing my investigation I noticed that our nicely written doc comments for the Disposer* classes don't really describe how the DisposerTarget is used, so I'll try to describe that here: Basically, a naive user of Disposer might have a Java object which points at some native data and they will want to register that object with the Disposer along with some code to dispose the native data. A problem typically arises in that such objects typically also hold references to a lot of other data. Since that object was registered in a queue to track its lifetime, that other data can be prevented from being garbage collected while the Disposer queue is later processed. The time might be small, but if the subordinate data is large and you need it collected right away to satisfy other allocations, you can run into OutOfMemory situations a lot more easily. The workaround is to register a different object in the queues - one that has the same lifetime as the original object which holds the native resources, but which holds on to little (or nothing) else so its footprint is small. The DisposerTarget interface allows the Disposer to ask the object being registered if it has a proxy object to stand in for it in the queues. We use that a lot since most of our classes with native resources hold on to a lot of data and we don't want them hanging around in a queue during the Disposer cycle. You can look at the src/share/classes/sun/java2d/SurfaceData.java class for an example of how DisposerTarget is used... ...jim Dmitri Trembovetski wrote: Hi Gili, you can take a look at the source at http://openjdk.java.net, see j2se/src/share/classes/sun/java2d/Disposer*.java j2se/src/share/native/sun/java2d/Disposer.c/h It's relatively well documented.. But shortly, it uses ReferenceQueue and WeakReferences. It puts a weak reference to the tracked object into a reference queue and when the object is gone the reference is retrieved from the queue, it disposes the resources associated with the object (those resources are kept in a special DisposerRecord object). Thanks, Dmitri [EMAIL PROTECTED] wrote: Hi, The following two BugParade issues discuss how Sun replaced class finalizers using the Java2D Disposer mechanism: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6247526 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6299405 This peaked my curiosity, how does this mechanism work? Thank you, Gili [Message sent by forum member 'cowwoc' (cowwoc)] http://forums.java.net/jive/thread.jspa?messageID=239660 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Java2D Disposer mechanism
There are 2 advantages to Disposer: - priority of disposal process - the DisposerTarget mechanism One problem with the finalize method is that they intentionally leave some of the aspects of the process undocumented. One thing that is not documented is the priority of the finalizer thread - which is actually fairly low. Thus, finalization is not very prompt in the grand scheme of things and the Java code cannot control that. We asked for finalization to be increased in priority, but due to compatibility it was decided to leave it with a low priority. With Disposer, we can control the priority of the thread managing the queue. The other problem with finalize() that others have mentioned is that the object with the finalize() method needs to remain alive. Often, that is a complicated object that has ancillary data that you don't want to keep alive for another round of GC. Disposer provides the DisposerTarget mechanism to deal with a similar problem and so you can use Disposer without keeping the original object around during the disposal process. Of course, that latter issue can be managed with finalize() methods as well. It is common practice to put the finalize() method on the class that manages the native resources, but one could just as easily have created an instance of a tiny subclass that is stored as a reference from the main object and put the finalize() method on the subclass so the parent can go away and leave that tiny child around in the finalizer queue. The main thing is that programmers don't often want to design this way, and so they don't - but DisposerTarget makes this paradigm more straightforward so it is easier and more likely that the right thing will be done... ...jim [EMAIL PROTECTED] wrote: Why would it be cheaper to use WeakReferences to track disposable objects than it would be to use finalizers? Don't both essentially delay garbage-collection and don't both only get flagged as disposable at the GC's discretion? At least with finalizers you're guaranteed that objects will get GC before OutOfMemoryError is thrown, with the WeakReference approach don't you run the risk that you'll run out of native resources and throw OutOfMemoryError when you don't really have to? Thanks, Gili But shortly, it uses ReferenceQueue and WeakReferences. It puts a weak reference to the tracked object into a reference queue and when the object is gone the reference is retrieved from the queue, it disposes the resources associated with the object (those resources are kept in a special DisposerRecord object). [Message sent by forum member 'cowwoc' (cowwoc)] http://forums.java.net/jive/thread.jspa?messageID=239733 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Why integers and not doubles for java.awt.Polygon?
Polygon and Rectangle were part of the original integer-based AWT Graphics API before it was fleshed out in Java 2 to become the 2D API that we know today. Thus it makes sense that Polygon was created as an integer polygon (for handing directly to the platform APIs that did all of the rendering before we created our own rendering pipelines in Java 2). The remaining question then is why we didn't create a 2D superclass for Polygon like we did for Rectangle[2D] and Point[2D] and there isn't a great answer to that. We did create GeneralPath in Java 2, which can handle polygons and much more, but it fell outside of the typical design pattern used for all of the other geom classes (Foo2D with inner subclasses Foo2D.Float and Foo2D.Double). In 1.6 we finally upgraded GeneralPath by creating Path2D(.Float and .Double) and making GeneralPath a trivial subclass of Path2D.Float, but we've never done anything similar with the Polygon [non-]hierarchy. Path2D (and GeneralPath) is powerful enough to be a non-integer-based Polygon so having Polygon2D would be partially redundant. One could view Path2D as the geom hierarchy virtual parents of Polygon except that Polygon is unable to subclass them directly since it can provide only a subset of their API. That doesn't preclude Polygon2D, but it makes it much less critical in its absence and potentially detrimental to add at this time to avoid API/code bloating. ...jim [EMAIL PROTECTED] wrote: Hi, I would like to know why java.awt.Polygon is constructed with integers as opposed to doubles. I want to create a Polygon from an array of Point2D.Double objects, and now face the challenge of having to change all coordinates to integer values. Is there any other way around this? Thanks [Message sent by forum member 'deirdre' (deirdre)] http://forums.java.net/jive/thread.jspa?messageID=236261 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Why integers and not doubles for java.awt.Polygon?
Olivier Lefevre wrote: GeneralPath in Java 2 [...] can handle polygons and much more API-wise yes but is there a performance angle or is Polygon really redundant now? It depends on how you would use Polygon as to whether or not there would be a performance penalty or not. First, there are 2 sides to the story - how fast it is for your program to maintain the Polygon[2D] versus maintaining a Path2D - and how fast can we render each Shape type. With respect to setting up the polygon, the Polygon class has this nice exposed data structure that might let some applications just copy some new data in as fast as an arraycopy and that could be a great performance boon for those specific operations. But, there is some pain associated with exposed data structures insofar as the object cannot really trust any cached information about its internal data whereas an object with hidden structures can. In the end, most design books would recommend that objects are better off hiding their internal fields behind fast accessors, both for maintaining correctness, and for opening themselves up to possible optimizations for trusted code. So, this particular advantage of Polygon is dubious at best. In contrast, Path2D and GeneralPath hide their data and provide many methods for manipulating the data. If those methods map onto your needs well then you can usually set one up optimally. As with any API, there may be some applications that might find the specific methods they provide insufficient and working around with them might not be as optimal. YMMV. Space-wise the Path2D objects boil down mostly into a pointer to an array of floats or doubles for storing coordinates, and a pointer to an array of bytes for storing path types. A Polygon2D.Float would take 8 bytes per vertex (2xfloat) vs. 9 bytes per vertex for a Path2D.Float. The Double versions would take 16 vs. 17 bytes per vertex. The added space is not huge, especially for double data. In the end, though, with today's machines being as fast as they are, unless you are constantly updating the geometry in the polygon in an inner rendering loop there shouldn't be any performance issues there. With respect to rendering, if all things were equal - if all shapes were treated as generic shapes by the renderer - then there would be little performance difference between the two. But, not all things are equal. Some pipelines can take a Polygon directly and render it, others treat all shapes by getting their PathIterator. We also have some pipes internally that copy all shapes into a Path2D.Float and then render that directly (the native code digs in and grabs the necessary data directly). So, sometimes a Polygon object might be faster than an equivalently defined Path2D, in other cases it might be slower. And, it may depend on (and vary by) whether you render with a solid color vs. alpha, or with a more complex Paint, or with a wide stroke, etc. But, even if we created Polygon2D with Float and Double variants, there would still be some work required to do anything more specific than to just treat it like an everyday shape and ask for its PathIterator. There would have to be a trade off between the pipelines looking for Polygon2D.Float and Polygon2D.Double and writing new code to render them directly, added to the code that already might special case the Path2D equivalents, and we'd end up with a lot more code to enable the Polygon2D hierarchy - or we might avoid the added code and just treat them as any generic Shape - in which case they would definitely not be any more advantageous than using a Path2D. There wouldn't be much performance difference between the two if they boiled down to iterating their PathIterators. It would be best to measure your particular use case to find out, but I'm not sure one use case would constitute grounds for adding even more Shape variants to the base APIs. If there is significant overhead you find in setting up a Path2D, but the rendering isn't an issue, then you could always create your own Polygon2D with maybe an hours work (copy the Polygon code and just upgrade the storage). Note that in 1.6 there are even helper methods in Path2D for computing the answers for the intersects() and contains() methods which are the more difficult parts of a Shape API. And if so why not deprecate it since you are concerned about API bloat? With regards to deprecation - deprecation was common back in the early days of 1.1 and even 1.2 when it was new - all APIs that weren't the latest greatest were deprecated, but it got to a point where deprecation didn't really mean much any more. The general philosophy these days is to deprecate something only if there are specific problems associated with its use that cannot be worked around. A Polygon is still perfectly useful for the original purpose for which it was designed, and so not worthy of deprecation. But, the fact that Polygon is not worth deprecating doesn't necessarily mean that
Re: [JAVA2D] Why was java.awt.geom.GeneralPath made final?
It is made final to lock in its implementation since internal code relies on its internal structure. In 1.6 it is just a thin veneer over Path2D.Float which is not final (though its implementation-based methods are final). Out of curiosity - why are you wanting to subclass it? ...jim Olivier Lefevre wrote: Subject says it all. Thanks, -- O.L. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] What's a trick way to clamp a byte to 255 - 0? -- slowness fixed
The premultiplication problem will not be an issue for my little interpolator since I do not composite. But it would be for someone trying to use my interpolator for another purpose than what it was designed for. You said that you don't need have the premultiplication problem because you do not composite, but I wanted to be clear about the terminology here in case someone else comes across this thread. The premultiplied form should be used if you have alpha in the images, whether or not you composite. After reading your description it sounds like your images don't have or need alpha since you are simply doing panoramic stretching of opaque photographs, right? So, it's really the lack of an alpha channel which means that the premultiplied issue isn't applicable here, not the lack of compositing... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] AffineTransformation
I wanted to follow up this suggestion with a warning. The Area object is not a generalized Shape. It has some very specific properties which make it inappropriate for some Shapes. Most of these should be documented in the latest javadoc for the Area class. 1. Area cannot represent shapes which enclose no space, such as a Line. Line2D is a Shape since it has a path and can be stroked, but it cannot be filled. An Area constructed from a Line2D is an empty Area containing no geometry since an Area only represents enclosed regions of space. 2. Area will implicitly close a Shape upon construction. If you define an open triangle consisting of 2 lines and you draw that Shape then only 2 lines will be drawn. If you construct an Area from that Shape and then draw the Area, 3 lines will get drawn to represent the closed triangle. 3. Area performs a *lot* of calculations on a Shape when you construct it. The purpose of these calculations is to internalize a representation of the regions of space that are enclosed to make the CAG operations (union, intersect, subtract, xor) easy to implement. Those calculations are pretty fast if your goal is to perform CAG with the Shape, but they are unnecessary if you are not using it to perform any CAG. The CAG operations go much faster because of these precalculations, but if your only goal is to use Area to make a Shape relocatable then the Area class (and its corresponding caveats and precalculations) is overkill. 4. When you use the Area.transform(AT) method, the precalculations that were done when the Area was constructed must be reexecuted and that takes additional time as well. As a result, I wouldn't use the Area class unless you are planning to perform CAG operations on the Shapes. However, the GeneralPath class (and now Path2D in JDK 6) offers very similar capabilities. There is a GeneralPath.transform(AT) method just as on the Area class. The even better news is that GeneralPath is simply a repository of geometry, unlike Area, so it is very fast to create one from an arbitrary Shape and it is also fast to transform it. In the end, though, if you are having to implement any kind of mechanism to manage your Shape objects, I would put translation (and other transformation information) into that architecture and go for a full Model/View approach rather than look to transform the Shapes themselves... ...jim [EMAIL PROTECTED] wrote: Hi swv, I'm definitely not comfortable with my own Java2D capabilities but recently I've been working with the Area class alot and I think you should take alook at it. It is a mutable shape implementation as far as I know - take alook at Area.transform(AffineTransform at). With this you wouldn't have to translate your Graphics object at all, and your areas will still be where you left them the next time paint is called. Also, Area can take any Shape in its constructor and it will try to construct a suitable Area interpretation of the given shape. Just remember to translate the new Area as necessary. I hope this may be of some assistance. Regards, Pierre [Message sent by forum member 'irond13' (irond13)] http://forums.java.net/jive/thread.jspa?messageID=228441 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] AffineTransformation
[I sent this earlier, but it doesn't appear to have gone anywhere so I am resending it in hopes that it makes it through to the forum and mailing list to clarify things. Apologies if this causes duplicate messages for some...jim] That translates the device space 100 pixels over. Great. But the next time I invoke paint, the device space is back to 0,0, as if I never told the graphics to move over 100 pixels. The documentation for the Component.paint(Graphics g) method: http://java.sun.com/javase/6/docs/api/java/awt/Component.html#paint(java.awt.Graphics) has a pointer to a technical article which describes the paint model in detail: http://java.sun.com/products/jfc/tsc/articles/painting/ It includes the following text: When AWT invokes this method, the Graphics object parameter is pre-configured with the appropriate state for drawing on this particular component: * The Graphics object's color is set to the component's foreground property. * The Graphics object's font is set to the component's font property. * The Graphics object's translation is set such that the coordinate (0,0) represents the upper left corner of the component. * The Graphics object's clip rectangle is set to the area of the component that is in need of repainting. Basically, the paint() method is always called with a brand new Graphics object. The Graphics object you use during one call to paint() is disposed soon after your paint() method returns so any remaining state on it is simply lost. The system was not designed to persist state from one call to the next, but to always start your paint() method with a consistent inherited state - any state requirements beyond the above conditions should be maintained separately by your application and applied each time the method is called. The article goes into much more detail about the architecture and is a recommended reading for anyone trying to do more than some basic rendering and management of graphics state... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Why isn't BILINEAR scaling smarter?
[I sent this out a few days ago, but replied to the wrong address so I don't believe it went through - sending again...jim] The Bilinear filtering algorithm is a well known algorithm that has a very specific definition which we follow. If we automatically applied multiple steps based on the scaling factor then we would violate that definition and have to call it something else. On a more practical note, if someone has determined that the caveats of the bilinear algorithm are sufficient for their needs and we did perform multiple steps instead of one step then we would reduce performance which that particular developer might not appreciate. On another practical note, hardware accelerators do not perform multi-step scaling so we wouldn't be able to fire the request off to the video card and get hardware accelerated scaling (nearly free) if we instituted such a policy behind the scenes. If we did provide that mechanism automatically then it would have to be under a different name so that the developer could buy into the specific tradeoffs that it provides (better quality for 2x downscaling at the expense of about 7x performance). In the meantime, we publish blogs like the one you point to in order to educate our programmers about the definitions of the graphical terms and processes that our APIs allow them to access and how to use those well defined industry standard mechanisms to achieve their needs... ...jim [EMAIL PROTECTED] wrote: There is an article that mentions that one can improve the look of downscaling using BILINEAR by downscaling multiple times (each time by half): http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html The paragraph in question reads: To combat this issue, you can use a multi-step approach when downscaling by more than two times; this helps prevent the information loss issue and produces a much higher quality result that is visually quite close to that produced by Image.SCALE_AREA_AVERAGING My question is, why doesn't Java do this automatically under the hood? If I request BILINEAR or BICUBIC downscaling for a factor greater than two, why doesn't Java either do multistep scaling on my behalf or why doesn't the Java2D team add a new hint (to maintain backwards compatibility) which will tell Java2D to apply these filters using the multi-step method? I would much rather have this supported by the JDK than having people reinvent the wheel over and over. Thank you, Gili [Message sent by forum member 'cowwoc' (cowwoc)] http://forums.java.net/jive/thread.jspa?messageID=227363 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] JVM Hangs on multit hreaded Image resizer
[I sent this out a few days ago, but my mailer replied to the wrong header address so it never went anywhere - sending again to the list in hopes it can still clarify some things...jim] Hi Nick, [EMAIL PROTECTED] wrote: Now for the real problem. I'm running the following code with 4 threads. I've read that the Graphics2D code is not thread safe, so I've synchronized it. However, the convert method hangs on the next thread dump: A given Graphics2D object can only be used on a single thread at a time, but you can be using separate Graphics2D objects concurrently in separate threads as much as you want. Thus, the MUTEX in your code below is unnecessary. pool-1-thread-3 prio=1 tid=0x8c9b81a0 nid=0x1e56 runnable [0x8a533000..0x8a5337f0] at sun.java2d.loops.ScaledBlit.Scale(Native Method) at sun.java2d.pipe.DrawImage.scaleSurfaceData(DrawImage.java:850) at sun.java2d.pipe.DrawImage.renderImageScale(DrawImage.java:505) at sun.java2d.pipe.DrawImage.tryCopyOrScale(DrawImage.java:287) at sun.java2d.pipe.DrawImage.transformImage(DrawImage.java:171) at sun.java2d.pipe.DrawImage.transformImage(DrawImage.java:947) at sun.java2d.pipe.ValidatePipe.transformImage(ValidatePipe.java:212) at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:2969) at sun.java2d.SunGraphics2D.drawRenderedImage(SunGraphics2D.java:2392) at test.ImageCallable.convert(ImageCallable.java:90) Can you isolate the specific scaling call into an isolated test case? Since the thread is runnable, I'm guessing that the specific request to scale an image in this case is running into an infinite loop (or perhaps it is asking for a huge scale that is just taking a long time?) //Native code behind drawRenderedImage is not thread safe. synchronized (GRAPHICS_MUTEX) { Graphics2D g = bufferedImageDst.createGraphics(); g.drawRenderedImage(imageSource, transform); // - the problem line g.dispose(); } Note that the use of this particular Graphics2D object all occurs on a single thread so it does not need to be synchronized... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] AffineTransformation
rectangle.getBounds().setLocation(shapeLocation) which doesn't work I think this is the source of your misunderstanding (that snippet of code was never intended to work) which you found out later in the thread you linked in: which is where my misunderstanding started from, also on this post- http://forums.java.net/jive/thread.jspa?messageID=228037 Basically, to modify the Shape you need to invoke a method on the original object. The Shape interface only includes methods to ask for information about the Shape, not to modify the Shape. Even methods like getBounds which return an object are not meant to provide an indirect means to modify the object - the returned object is only an encapsulation of an answer that could not be expressed using a simple java type like an int or a boolean. The fact that some of the objects used as return values for these methods have methods of their own that make them mutable is a by-product of the fact that those objects have a life other than to be used as a return value. In other words, a Rectangle object is useful in many circumstances in which you might want to move them around - but in the case of the return value of getBounds(), it is only being used to house 4 numbers in a convenient and recognizable way... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] AffineTransformation
[EMAIL PROTECTED] wrote: Jim- right on and well said- that was exactly my confusion Kirillcool said: you're using core view classes in your model. The Shape and its derived classes are for painting on the screen. Although they might seem like a good option to use in the model, they aren't in most cases (as you're starting to see), since they're targeting the screen (view). Well Rectangle keeps state in just the way you say it shouldn't, if you mean by state enough information to draw it to the screen in a specific place. It has an x and a y and you can mutate those through it's methods and as a result of that mutation it will draw itself elsewhere. That's state. . I never said that Rectangle does not keep state. It does keep state. Nearly all Shape objects keep state and provide methods for you to modify that state in various ways (whatever was deemed useful for that Shape). What I said is that you cannot use the return value of the getBounds() method to manipulate the state of a Shape object, even if the original object was a Rectangle. You can modify the location of a Rectangle by calling the setLocation() method on *that* Rectangle object, but you cannot modify its location by calling the setLocation() on the object that is returned from its getBounds() method - just like any other Shape. The return value of Rectangle.getBounds() may be an instance of the Rectangle class, but it is a new instance that is not the same instance as the original. It stores the same x,y,w,h as the original, but it is a brand new object completely isolated from the original. For example: Rectangle r = new Rectangle(0, 0, 10, 10); // the following statement modifies r directly r.setLocation(5, 5); // setLocation was called on r directly // r now is located at 5,5 as compared to: Rectangle r = new Rectangle(0, 0, 10, 10); // the following statement modifies a temporary object // which is then dropped on the floor r.getBounds().setLocation(5, 5); // setLocation was called on the return value of setBounds() // *not* on r directly // r is still located at 0,0 as compared to: Shape s = // some shape // the following statement modifies a temporary object // which is then dropped on the floor s.getBounds().setLocation(5, 5); // original s is unaffected just like r in previous example Does that clear things up? ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Exception in thread Image Fetcher 0 java.lang.OutOfMemoryError: Java heap space
Hi Ken, QUESTION: does anyone have an idea of how to handle this situation? Shouldn't ImageFetcher.run() throw something? Like an OutOfMemoryError or something so that grabPixels() can throw an InterruptedException like the documentation says it will??? The ImageFetcher should capture any errors and pass on an ERROR condition to all ImageConsumers. Is that happening here? My suggestion would be to use ImageIO instead of the Toolkit image facility for a couple of reasons: - Getting pixels via PixelGrabber goes through some really indirect mechanisms that should be slower than ImageIO (YMMV as we haven't necessarily benchmarked your particular usage, but it would be a safe bet). - ImageIO does the image loading in your own thread so you can catch such errors and deal with them with a lot less fuss. - ImageIO will deliver you one single copy of the image - when you use PixelGrabber and Toolkit images then you run the risk of the Toolkit image storing the pixels itself and then also feeding them to your PixelGrabber which would double the amount of memory needed and the memory used for the Toolkit image is harder to control since it is managed by another mechanism (hint: Image.flush() should get rid of it, but be careful not to trigger it to reload the image data again in the future). To give you an idea - image.getWidth(canvas) is enough to trigger the Toolkit image to load and store its own version of the image. - Also, if the Toolkit image is loading its own version of the image in addition to the data it delivers to your PixelGrabber, that is even more of a performance loss. - (BTW, PixelGrabber can get the W/H itself and create an array for you if you use the PixelGrabber(image, 0, 0, -1, -1, forceRGB) constructor. That would avoid the second copy loaded for the Toolkit image problem...) Have you tried ImageIO? ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Exception in thread Image Fetcher 0 java.lang.OutOfMemoryError: Java heap space
Hi Ken, Ken Warner wrote: Hi Jim, You raise some interesting points. The reason I used Toolkit was because of the simplicity of the code that I needed to write. I wrote an early version of my applet using ImageIO and BufferedImage. The code ended up being pretty complicated. Right now I use Toolkit; grab the pixels; flush the image and do all my image manipulations on the raw one dimensional byte array returned by the PixelGrabber. Your code used a one dimensional int array - I'm presuming that was what you meant above. You could do something very similar with ImageIO, but you might have to use some of the more specific API calls. You can request an image to be read into a specific format of BufferedImage using the ImageReadParam, but you need to get an ImageReader directly, query it for the default ImageReadParam, and then change/set the destination. It's a few more lines than ImageIO.read(File), but it gets you an image in the default ARGB space that your PixelGrabber was using. Then you just need to dig out the int array from the BufferedImage: WritableRaster wr = bimg.getRaster(); DataBufferInt dbi = (DataBufferInt) wr.getDataBuffer(); int pixels[] = dbi.getData(); // voila - pixels in a one dimensional array Note that the cast will cause a problem if you aren't using a TYPE_INT_ARGB or TYPE_INT_RGB BufferedImage since the various formats use different types of DataBuffer objects under the hood. And I'm so far along in my development cycle that recoding for ImageIO (which is really good stuf - no slight intended) that recoding for ImageIO would set me back a month or more. If you only need to grab an int array from an image then ImageIO should be able to do that with just a few changes to your image loading code, unless I'm missing something...? The thing is, PixelGrabber implements the ImageConsumer interface. And the doc's say an InterruptedException is supposed to be raised -- I quote the doc's in my previous message -- but it's not. That's the problem. If it was -- I'd be home free. The thread I do the PixelGrabbing from is just suspended. All other threads are still up and running. The docs say that InterruptedException is raised if this thread is interrupted (i.e. via an explicit call to Thread.interrupt()) which isn't what is happening. On the other hand, the method should return if the producer calls imageComplete an ERROR flag. Unfortunately, the stack trace shows that the ImageFetcher thread is in a suspended state due to the OOM condition. In other words, the OOM was so severe that the thread could not even continue executing. It's hard for the thread to notify you of anything if the VM suspends it. This goes back to what another person said about OOM being one of those conditions that you can only cross your fingers and hope to survive. Some code may be able to wind its way out of an OOM if it catches the OOM in just the right place. Other code may be in the middle of a situation that it cannot back out of. And in this case it looks like even the VM can't figure out how to back out of the situation since it couldn't even make space for some local variables so it suspended the Thread. To be clear -- the image is downloaded; the image has been decoded by Toolkit; when I try to grab the pixels, my thread is suspended by ImageFetcher. It sounds like you are getting double copies of everything then since the grabbed pixels are separate storage from the version that was loaded by the Toolkit for use with drawImage. That's going to exacerbate your memory usage and make OOM more likely to happen. Also, your thread is not suspended by ImageFetcher per se - it is in a wait() call waiting to be notified that the appropriate data has been delivered - the data coming from the ImageFetcher thread. Once the ImageFetcher gets hit with an OOM, it can get summarily suspended as in the current case and cannot notify you of anything. That's not an easy situation to code for. There is a call to grabPixels that does take a timeout if you want to use that to avoid permanent suspension of the calling thread, but at that point your VM is so wedged that it had to suspend a system thread so I don't think your program would return to too much functionality. The way I fetch the image from the server is I just download it as a byte array then give it to Toolkit to decode. Really simple code. It all works with reasonable speed considering the usual constraints on downloading a 1 meg file over the internet. Giving it to ImageIO would only be a few more lines of code, not a complete rewrite of your package. Another handicap is that I don't have the source to class sun.awt.image.ImageFetcher extends java.lang.Thread It's one of those mystery classes. If I had source, a workaround might pop out at me. I'm afraid that this line from your stack trace: Thread [Image Fetcher 0] (Suspended (exception OutOfMemoryError))
Re: [JAVA2D] Exception in thread Image Fetcher 0 java.lang.OutOfMemoryError: Java heap space
I have a couple more items that may affect OOM when using the Toolkit image code... Try using the Toolkit.createImage(...) variants instead of the Toolkit.getImage(...) variants. The latter getImage calls all keep a copy of the image that was returned in an internal hashmap in case they get a future request for an image loaded from the same location. I think you said you were pre-loading the data into byte arrays before making a Toolkit image out of it in which case you are probably already using the createImage(byte array) call and there will be no implicit caching for that call. If you drop your reference to the original Image (and to the PixelGrabber that you construct with it), then call the Image.flush() method on the object before you drop your reference to it. This will cause the system to immediately flush all of the pixel data for the Toolkit version of the image - which won't affect your PixelGrabber copy at all - and the memory can be reclaimed more aggressively. It might be a good idea to call System.gc() after you flush the image and drop your reference(s) to it to be more proactive about keeping memory cleaned up. Finally, the code: int w = image.getWidth(canvas); int h = image.getHeight(canvas); int p[] = new int[w * h]; PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, p); // ... pg.grabPixels... is only reliable if you force the loading of the image before you call this code. If you do not preload the image then the calls to getWidth and getHeight might return -1 meaning the data isn't loaded yet. If you load the image from a local byte array of image data then the data might be decoded fast enough to be ready by the time you call getWidth and getHeight, but there is still potential for a race condition there. Finally, those calls to getWidth/Height(canvas) both cause the Toolkit image to populate itself with pixel data that you will likely never use since you only care about the copy in the PixelGrabber. The following code: PixelGrabber pg = new PixelGrabber(image, 0, 0, -1, -1, true); // ...pg.grabPixels... int w = pg.getWidth(); int h = pg.getHeight(); int p[] = (int[]) pg.getPixels(); will do the same thing, but never trigger the Toolkit image to load its internal copy of the data. The PG copy of the data will be the only one created. The width and height will be obtained by the PixelGrabber from the ImageConsumer stream and it will create an int[] array if you tell it to force the RGB colormodel with the last parameter true. Hopefully with one or more of these suggestions you can reduce your memory consumption and avoid OOM conditions for much longer... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Hi Mikael, [EMAIL PROTECTED] wrote: I don't know what to say. You go to great length explaining why circles aren't round and why the corner radius on rounded rectangles are different on the different sides, and why you will not fix it. I guess other platforms (Flash, .NET and similar) also have these problems since they aren't fixable? Actually, I wasn't sure - I just know that the rendering models that we use are fairly industry standard and there are well-known techniques for working around them, some can be implemented as heuristics within the rendering engine (along with a way to turn them off since they aren't always right) and we've done that, and others have to be implemented as care in how one constructs rendering requests. I know that we've exercised about as much magic as we know how to exercise internally here in the implementation in the heuristics we created for path normalization, but I believe there could be more magic, it just isn't something we have sitting in our back pocket and it can't be summoned up on command like a bug fix normally can. This isn't a case of whoops, we forgot to increment that variable or we should probably keep more bits of resolution here, this is a limitation of how advanced a set of heuristics we know how to create. And, like I said, I wasn't totally sure about Flash - but I went and downloaded it and played around with it for a few hours and discovered that, basically, they use a rendering model that is fairly close to what we've implemented - very close to the industry standard. If you render small circles with Flash you get fuzzy outlines on the circles. If you enable their form of stroke hinting then you get lopsided un-round (but still fuzzy) circles. At least in our case I believe the circles tend to be crisp (or at least our heuristics try to keep them crisp) even though they are lop-sided. The hinted circles I saw with Flash were neither crisp nor were they round. I then tried a few more experiments and found that many of the issues that people complain about with respect to Java2D rendering are exactly the behaviors that Flash produces (and they have some problems that we don't as well). I haven't done the same experiment with .NET, but in either case - if you have output from some other rendering engine that does what you want then please share a real-world example, rather than guessing about the other platforms. It turns out that it is too hard to do Java2D graphics in a high fidelity way, at least without resorting to hacks. And are you sure that it is possible with other systems? I'd like to see some examples. Another problem I have is that one can not in Java2D in a generic way outline and fill a Shape and make it look good. The outline will plot outside and inside the shape depending on the direction of the vector (in degrees). This is since you don't provide an INSIDE and OUTSIDE stroke. You have the hanging right/left stroke and the pure stroke. Flash provides a very similar rendering model. When you draw 1 pixel wide strokes at 1:1 scales you get the same hanging pen strokes that we render. The pure stroke isn't usable since you either get the lines sharing two pixels for vertical and horizontal lines or you do as you suggest and translate 0.5, in which case you get good lines but shapes that are one pixel too big. You get the one pixel too big problem with Flash too. The stroke follows the outline and straddles the path - therefore the stroked version will always be linewidth larger than the filled stroke. One CAN solve the one-pixel-too-big-shapes-when-using-PURE-and-translate.5-problem by scaling the output with ((width - 1.0)/width) but that only works for rectangles (shapes with equal but mirrored quadrants actually, so also for circles) but fails for general paths, polygons and composite shapes of all kinds. Scaling the output isn't a very general solution and can be tricky to get right with oblong shapes - even if they are convex - as you say. Other techniques for handling stroking involve things like: - stroke then fill (even widths == symmetric border) (odd widths and STROKE_NORMAL == uneven border) (odd widths and PURE == fuzzy symmetric border in AA) - fill then stroke (misalignment of stroke at odd sizes is hidden behind the stroke) - use linewidth=2x and stroke then fill (gives a 1 pixel outer/halo stroke, but needs a fill to carve out the stroke) - use linewidth=2x and compute [strokeShape SUB Shape] (gives a 1 pixel outer stroke shape) - use linewidth=2x and intersect strokeShape and Shape (gives a 1 pixel inner stroke shape) This problem has shown to unsolvable in a generic way. Only if one has prior knowledge about what type of shape to paint and are in full control of the rendering hints can one get good results for some types of shapes. You can not create
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Hi Mikael, Have you tried using the STROKE_PURE hint? ...jim [EMAIL PROTECTED] wrote: Hi Chris, I'll leave the AA thickness as explained in the reply to Kirill above. What bothers me a tad more is the flat circles that still haunts us. :) I think this is what is the problem with the Webstart app as well. It's solvable by using non-even sizes only though.. I'll try to post a screen shot of the problem here: p img src=http://www.migcalendar.com/ovals.png/ p Cheers, Mikael [Message sent by forum member 'mikaelgrev' (mikaelgrev)] http://forums.java.net/jive/thread.jspa?messageID=224733 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Making a BufferedImage managed
It would be nice to get a method in Image that allows me to 'make this Image object managed if possible' without this workaround. If you want more explicit control over acceleration then the best route would be to create your own VolatileImage objects and manage them yourself. That is essentially what we are doing with the managed images, except for two differences: - you are subject to our acceleration heuristics (which we can probably make more convenient with a well-considered RFE) - the original image object remains in the heap wasting memory if you only ever want the accelerated versions In particular, if you are managing a bunch of sprites, then having a load routine which gets the image from ImageIO, immediately creates, validates, and copies the loaded image into a VolatileImage, and then drops the reference to the original loaded sprite - that will save a lot of Java heap memory by not having duplicate copies laying around. The price for that efficiency and control, though, is that you will need to track when the images get unloaded... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] drawImage for video rendering
What values are you using for rMask, gMask and bMask? Internally we have native support for packed formats of xRGB, xBGR, ARGB, and RGBx. It the masks you are using don't match one of those formats then we may back off to some pretty generalized method call per pixel code which might explain the slow frame times you are seeing. If that is the case, then it may be faster for you to rearrange the components into one of those supported orders as you fill the array (a few shifts and masks) rather than rely on drawImage to do it automatically (with method calls, etc.). I submitted bug 6554473 on this which should show up on the bug parade in the next day or so. In the meantime, the workaround I mention above (doing your own bit shifting) can improve the performance to within about 3x of one of the supported formats. Even better would be to get ffmpeg to return the data in a format that matches one of our supported formats better... ...jim [EMAIL PROTECTED] wrote: I'm currently working on a new JNI wrapper for ffmpeg to play videos in Java without using the out-dated (and buggy) JMF library. This would allow to play virtually any audio/video file from the local file system, http, or rtp. The SWT version is already working fine, but the Java2D-based version for Swing does not have the needed performance. I have to display 25 frames per second and get the data either as int[] or byte[]. Any of a rather large number of palettes can be choosen within ffmpeg and scaling is also already done. In Java2D, I allocate a new image before the first frame is shown: int[] data = new int[width * height]; DataBufferInt dataBuffer = new DataBufferInt(data, data.length); DirectColorModel colorModel = new DirectColorModel(24, rMask, ...); SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, width, height, new int[] { rMask, gMask, bMask }); WritableRaster wr = Raster.createWritableRaster(sm, dataBuffer, new Point(0, 0)); image = new BufferedImage(colorModel, wr, true, null); Afterwards I just fill the data array with the new data and call g2d.drawImage(image, 0, 0, null); However, drawImage(..) takes about 15 to 30ms for a frame of size 608x336. Doing it almost the same way in SWT with an ImageData object takes only 0.5ms. Is there a way to improve performance? Or do I have to use either DirectX or OpenGL? It would be nice if it is compatible with JXPanel to support, for example, overlays. Moreover, as far as I have seen there is no NIO support in Java2D? Because this way I could get the data from ffmpeg without having to copy anything. Thanks, Remo [Message sent by forum member 'remmeier' (remmeier)] http://forums.java.net/jive/thread.jspa?messageID=215811 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] MemoryImageSource flickers when I update pixels with newPixels()...
If you simply return from update() without rendering anything then repaint() calls will have no effect. The typical way to relieve flickering is to have update() call paint() directly as in: public void update(Graphics g) { paint(g); } ...jim Ken Warner wrote: Jim, I figured out my problem. It had nothing to do with MemoryImageSource. It was all my own dumb mistake. I've been almost entirely programming in Swing for the last 5 years. Swing does all the buffering. I started a little applet project in AWT just to get a small, light, fast applet. It turns out that Component.update() either has changed or what I was doing before never had a problem with update(). update() clears the drawing area -- in this case a Canvas -- to the background color and then calls paint(). One must over ride update() to stop the flickering and tearing. I just override update in MyCanvas to a stub. update() { return; } Either I knew this once and forgot or it's changed since the last time I made my own custom component from Canvas. It was all me. And I pretty much am relying on BufferStrategy now so no offscreen drawing what so ever. It works flawlessly now. Thanks for responding Ken Jim Graham wrote: When you set the animated attribute to true on a MIS it will never be complete so drawImage will never return true. The return value of drawImage should probably be ignored for 99.99% of code - it doesn't tell you anything that you really need to know. All it is telling you is if all of the image data has been completely loaded from the source, but your ImageObserver will be notified when new data is available so there isn't much you need to do with the return value other than its informative (novelty?) value. In particular, if you immediately reissue the drawImage call it will paint exactly the same thing it painted the previous time until new data arrives (which isn't likely to happen if you are wasting all of the CPU time repainting something that hasn't changed yet). With respect to the change in behavior in 1.4 vs. 1.5, I'm not sure what might be causing that without a standalone test case. The only odd thing I see is that you are double buffering things - dumping pixels into canvasImage with newPixels and then immediately transferring them to buffer with drawImage and later the pixels get dumped from buffer to the screen with the drawImage in the paint method - why not just use the drawImage to the screen directly? ...jim Ken Warner wrote: I'm haveing a strange problem -- I've used MemoryImageSource before with great success. But now, doing the same thing I've done before in Java 1.4 I'm getting flickering on newPixels() in Java 1.5... That is, when I send new pixels to my MemoryImageSource mis and repaint() the image flickers badly. Didn't do this in 1.4. The odd thing is that -- while((status = bg.drawImage(canvasImage,0,0,thisW, thisH,this)) == false); never breaks because bg.drawImage never returns true. Do I have to use a MediaTracker or something??? Here's what I'm doing -- I've tried it using BufferStrategy and get the same flicker //this is an AWT Canvas private Image canvasImage = null; private Image buffer = null; private Graphics2D bg = null; private MemoryImageSource mis = null; private ColorModel cm = null; init() { thisW = this.getWidth(); thisH = this.getHeight(); mis = new MemoryImageSource(thisW,thisH,pixels,0,thisW); mis.setAnimated(true); mis.setFullBufferUpdates(true); canvasImage = this.createImage(mis); buffer = this.createImage(thisW, thisH); bg = (Graphics2D)buffer.getGraphics(); } public void paint(Graphics g) { g.drawImage(buffer,0,0,thisW, thisH,this); } public void newPixels(int [] newPixels) { mis.newPixels(newPixels, ColorModel.getRGBdefault(),0, thisW); boolean status = false; //while((status = bg.drawImage(canvasImage,0,0,thisW, thisH,this)) == false); bg.drawImage(canvasImage,0,0,thisW, thisH,this); this.repaint(); } === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] MemoryImageSource flickers when I update pixels with newPixels()...
When you set the animated attribute to true on a MIS it will never be complete so drawImage will never return true. The return value of drawImage should probably be ignored for 99.99% of code - it doesn't tell you anything that you really need to know. All it is telling you is if all of the image data has been completely loaded from the source, but your ImageObserver will be notified when new data is available so there isn't much you need to do with the return value other than its informative (novelty?) value. In particular, if you immediately reissue the drawImage call it will paint exactly the same thing it painted the previous time until new data arrives (which isn't likely to happen if you are wasting all of the CPU time repainting something that hasn't changed yet). With respect to the change in behavior in 1.4 vs. 1.5, I'm not sure what might be causing that without a standalone test case. The only odd thing I see is that you are double buffering things - dumping pixels into canvasImage with newPixels and then immediately transferring them to buffer with drawImage and later the pixels get dumped from buffer to the screen with the drawImage in the paint method - why not just use the drawImage to the screen directly? ...jim Ken Warner wrote: I'm haveing a strange problem -- I've used MemoryImageSource before with great success. But now, doing the same thing I've done before in Java 1.4 I'm getting flickering on newPixels() in Java 1.5... That is, when I send new pixels to my MemoryImageSource mis and repaint() the image flickers badly. Didn't do this in 1.4. The odd thing is that -- while((status = bg.drawImage(canvasImage,0,0,thisW, thisH,this)) == false); never breaks because bg.drawImage never returns true. Do I have to use a MediaTracker or something??? Here's what I'm doing -- I've tried it using BufferStrategy and get the same flicker //this is an AWT Canvas private Image canvasImage = null; private Image buffer = null; private Graphics2D bg = null; private MemoryImageSource mis = null; private ColorModel cm = null; init() { thisW = this.getWidth(); thisH = this.getHeight(); mis = new MemoryImageSource(thisW,thisH,pixels,0,thisW); mis.setAnimated(true); mis.setFullBufferUpdates(true); canvasImage = this.createImage(mis); buffer = this.createImage(thisW, thisH); bg = (Graphics2D)buffer.getGraphics(); } public void paint(Graphics g) { g.drawImage(buffer,0,0,thisW, thisH,this); } public void newPixels(int [] newPixels) { mis.newPixels(newPixels, ColorModel.getRGBdefault(),0, thisW); boolean status = false; //while((status = bg.drawImage(canvasImage,0,0,thisW, thisH,this)) == false); bg.drawImage(canvasImage,0,0,thisW, thisH,this); this.repaint(); } === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Graphics2D.fill threads locking
The AA pipeline currently works by feeding the path to the renderer, then looping along getting chunks of graybits coverage values for each piece of the shape. Each chunk of graybits is then used to color the destination surface. Most of this code is reentrant, but one critical piece is not - the code that creates a chunk of graybits from the digested path. Unfortunately, the existing implementation (which is running on 8-10 years old now) was written to use some fairly large internal data structures that were considered too expensive to create fresh for each renderer/thread. Fixing that may not be trivial, but we are evaluating right now if we should replace the renderer with a newer renderer due to other issues so we can keep multi-threading performance in mind during that evaluation (and this may be another straw on the camel's back). Please file an RFE on this with some of your stack traces... ...jim [EMAIL PROTECTED] wrote: Looking into DuctusRenderer it has synchronized methods which might explain the locks. I guess the way we're using this is bad. How can help improve? Thanks, Stéphane [Message sent by forum member 'stephanenicoll' (stephanenicoll)] http://forums.java.net/jive/thread.jspa?messageID=188529 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Area's constructive area geometry
Currently the only mechanism to get access to these sources is via the Peabody project: http://java.sun.com/developer/technicalArticles/J2SE/peabody/ You will have to sign a contributor agreement to see the source code as is described on that page. The code was developed completely in house based on standard principles of dealing with curve and line geometry (i.e. curve subdivision, bezier bounding boxes and convex hulls, etc.). You can google for bezier curve intersection to find a number of academic papers on algorithms... ...jim Brien Colwell wrote: hi All, Does anyone know how to obtain the sources to the AreaOp classes? I'm curious to see how its Constructive Area Geometry is implemented -- I guess just seeing the add op will illuminate a lot. Also, does anyone know if this is a proprietary Sun technology or based on some known comp. geom. work? I find it very cool! Brien === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] graphics and ints
Have you tried setting the STROKE_CONTROL hint to PURE? The default is NORMALIZE which allows the renderer to round various values so that line widths appear uniform (though they are sticky to the integers as a result). The PURE setting tells the renderer to honor sub-pixel positions more closely... ...jim [EMAIL PROTECTED] wrote: Hi Chris, I did try antialiasing. And it is good enough on large scale just as you said. However the images will be used on a scale from 20 x 20 or 40 x 40. I was hoping i could give the line_width as a double in my stroke. And let graphics do something 'reasonable' with it when antialiasing is activated. I have no clue how I could have more control at this moment. Maybe I have to write wrappers around some classes. Thanks for the response. [Message sent by forum member 'andries_demont' (andries_demont)] http://forums.java.net/jive/thread.jspa?messageID=170650 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Expanding a shape
This all depends on your definition of expand shape. The code snippet below expands the shape by d distance perpendicular to every point on the outline of the shape without regard to the center of the shape. In other words, the resulting shape includes all points that were within the original shape and also all other points that were within d distance from the interior of the original shape. I am not familiar enough with what you are trying to accomplish in order to suggest a solution. Are you simply trying to scale the shape outward from its geometrical center? I'm not sure what you mean by geometrical center, though - is that an average of all of the points on the outline? Or is it an average of all of the interior points? Or an average of the bounds? Or is it something else? ...jim Yinhe Cao wrote: I have checked the interface Area, and there is no method to compute the geometrical center of the area such as: Point2D center() The point is if the area interface is extended to incluse the center method, expandShape method should be very simple and direct to implement by using AffineTransform. Yinhe Cao Jim Graham wrote On 07/17/06 14:39 You can use the Area class to add in the original Shape: public Shape expandShape(Shape s, float d) { BasicStroke bs = new BasicStroke(d); // or new BasicStroke(d, CAP_ROUND, JOIN_ROUND); Area a = new Area(bs.createStrokedShape(s)); a.add(new Area(s); return a; } Note that the JOIN setting by default is MITER which may not match your expectations for what it means to expand the boundary of a Shape. ROUND would result in a smoother resulting outline... ...jim Chris Nokleberg wrote: I'd like to expand the boundary of an arbitrary Shape. If I use a BasicStroke createTransformedShape, the result is perfect except for the resulting hole. I currently get rid of the hole by iterating over the path, splitting the shape into multiple subshapes, and then comparing the bounds of each subshape to find the outermost one. This is bunch of work just to undo the unnecessary work BasicStroke has already done, though. Any suggestions on a cleaner solution? Thanks, Chris === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Expanding a shape
Sorry, that was where the CAP and JOIN settings came into effect with the code. You can choose from among those options you list depending on how you set the CAP and JOIN. And, of course, having said that I just realized one potential bug in the cited code. If the path is not closed then the stroke shape will not include the last segment back to the start of the path. Filling a shape (and executing new Area(Shape)) both implicitly close all sub-paths, but createStrokedShape does not. So, the code below only really works correctly for explicitly closed shapes. With a slight modification, it could be made to work with unclosed shapes by writing a ClosedShape wrapper - left as an exercise for the reader... ;-) ...jim Yinhe Cao wrote: Jim, Thanks for the clarification. Now I know exactly what your expand shape means. Your definition is crystal clear except at those corners where the outer normal directions are not well defined. Are you going to closed the gap with an arch of radius d, or simply extends the outer edges? For small d, there is no much difference, but for a large d, the difference will be visible. Thanks, Yinhe Jim Graham wrote On 08/22/06 15:44,: This all depends on your definition of expand shape. The code snippet below expands the shape by d distance perpendicular to every point on the outline of the shape without regard to the center of the shape. In other words, the resulting shape includes all points that were within the original shape and also all other points that were within d distance from the interior of the original shape. I am not familiar enough with what you are trying to accomplish in order to suggest a solution. Are you simply trying to scale the shape outward from its geometrical center? I'm not sure what you mean by geometrical center, though - is that an average of all of the points on the outline? Or is it an average of all of the interior points? Or an average of the bounds? Or is it something else? ...jim Yinhe Cao wrote: I have checked the interface Area, and there is no method to compute the geometrical center of the area such as: Point2D center() The point is if the area interface is extended to incluse the center method, expandShape method should be very simple and direct to implement by using AffineTransform. Yinhe Cao Jim Graham wrote On 07/17/06 14:39 You can use the Area class to add in the original Shape: public Shape expandShape(Shape s, float d) { BasicStroke bs = new BasicStroke(d); // or new BasicStroke(d, CAP_ROUND, JOIN_ROUND); Area a = new Area(bs.createStrokedShape(s)); a.add(new Area(s); return a; } Note that the JOIN setting by default is MITER which may not match your expectations for what it means to expand the boundary of a Shape. ROUND would result in a smoother resulting outline... ...jim Chris Nokleberg wrote: I'd like to expand the boundary of an arbitrary Shape. If I use a BasicStroke createTransformedShape, the result is perfect except for the resulting hole. I currently get rid of the hole by iterating over the path, splitting the shape into multiple subshapes, and then comparing the bounds of each subshape to find the outermost one. This is bunch of work just to undo the unnecessary work BasicStroke has already done, though. Any suggestions on a cleaner solution? Thanks, Chris === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] VolatileImage of a type like those from BufferedImage
I'm curious what your goals are here so that we can understand if we are aware of your needs for future API development. The usual reason for specifying a storage format is that you need to access the pixels directly and so you need to know how they will be stored in the image buffers. But with a VolatileImage, the pixels are not accessible so the storage format is not directly relevant to using it. Are you looking to choose a smaller format to save memory? Are you looking to make sure that the image has RGB (or A) channels or is grayscale? Some other need? ...jim [EMAIL PROTECTED] wrote: I am curious if there is possible to create a VolatileImage with a specific type ? And when I say type I reffer to those types from the BufferedImage class: TYPE_INT_ARGB, TYPE_BYTE_GRAY, etc. Sarmis [Message sent by forum member 'jsarmis' (jsarmis)] http://forums.java.net/jive/thread.jspa?messageID=140383 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] VolatileImage of a type like those from BufferedImage
Another issue is that the getSubImage() method on BufferedImage currently revokes the ability to manage either the parent or the child image. This prevents us from caching or accelerating either image in the future permanently. Thus, with this code you don't even get the benefits of managed images any more either. On the other hand, for a back buffer which is most often rendered to once for each display on the screen, a managed image doesn't offer much in terms of acceleration anyway due to the design that Chet details below. We are working on mechanisms which track the image data at lower levels so that they aren't fooled by this dual access to the image data and which can continue managing (caching, accelerating) the images after you get a subImage or get the DataBuffer, but that work will be post-Mustang... ...jim Chet Haase wrote: Managed Images are typically only accelerated for operations that copy-from the image to an accelerated destination. This is because we must retain the original bits of a managed image in memory that cannot be lost, as VRAM images on Windows may be. For scenarios where an image is rendered to once, or infrequently, managed images are probably a better approach because then you don't have to worry about handling the acceleration/loss issues. For scenarios where you are rendering to the image frequently (as Swing does for its back buffer), a VolatileImage can be more useful because: - we accelerate some operations to that image - the image will actually be accelerated (which may not be the case for a managed image rendered to frequently) So for your example below, you're effectively eliminating the possibility of using an accelerated back buffer. Whether this affects the overall performance of your application depends on what your app is trying to do and the type and frequency of rendering operations that you are performing. Chet. [EMAIL PROTECTED] wrote: Googling for this I have found this: http://swingwt.sourceforge.net/javadoc/swingwt/awt/image/VolatileImage.html but that is in another Swing implementation. As of JDK 1.5, all the buffered images created using the constructors of the BufferedImage class are managed images. Given that, using VolatileImage as a back buffer in RepaintManager does still offer a significant performance improvment ? I am asking this because I've done a nice thing with RepaintManager: [code] package myjavaextension.swing; import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.RepaintManager; public class BlackAndWhiteRepaintManager extends RepaintManager { private BufferedImage offscreenBuffer; public BlackAndWhiteRepaintManager() { super(); init(); } private void init() { Dimension maximumSize = super.getDoubleBufferMaximumSize(); offscreenBuffer = new BufferedImage( maximumSize.width, maximumSize.height, BufferedImage.TYPE_BYTE_GRAY ); } @Override public Image getOffscreenBuffer( Component c, int proposedWidth, int proposedHeight ) { return offscreenBuffer.getSubimage( 0, 0, proposedWidth, proposedHeight ); } @Override public Image getVolatileOffscreenBuffer( Component c, int proposedWidth, int proposedHeight ) { return null; } } [/code] Installing this repaint manager will render a gray UI. But I am affraid that the performance of using VolatileImage as a back buffer is lost. [Message sent by forum member 'jsarmis' (jsarmis)] http://forums.java.net/jive/thread.jspa?messageID=140430 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] How to do pixel based animation instead of MemoryImageSource?
There are really 2 questions here: - How do I manipulate a BufferedImage without interfering with its ability to be accelerated under the covers? - Is there a type of image that lives in hardware accelerated memory and to which I can write directly to its pixels? To answer the first question, first note that the type of hardware acceleration provided by a BufferedImage is very limited. It is what we call a managed image which means that we can cache a copy of that image in display memory if you copy it there frequently, but that copy in the display memory is not where the pixels live - it is only a cached copy. To avoid interfering with this managed image mechanism, you would currently have to use the relatively high level methods on BufferedImage and Raster and these are not as fast as manipulating the pixel array directly. This concern doesn't really apply to your case, though, since you modify all of the pixels in the image each time you copy it to the screen and a managed image only provides benefit on the second and subsequent times you render it to the screen. (The first time you render it to a screen or VolatileImage, the data must be uploaded to the display card whether it is going directly to the screen/VolatileImage or whether it is going to the cached copy. Either way, you still pay the performance penalty to get the pixels across the bus to the card.) The answer to the second question is that we currently have no image type which has directly accessible pixels and which also lives in accelerated memory - sort of an uploadable texture type of object. That kind of image is on our wish list, but we have no schedule for delivery of it yet... ...jim This is my applet prototype: = public class Viewer extends Applet implements Runnable { int[] idata = null; // image pixel data array Image view = null; // viewport int[] vdata = null; // view data array Image offImage = null; // Offscreen rendering image Graphics offGraphics = null; // Offscreen rendering graphics context int offwidth = 0; // Width of the offscreen graphics int offheight = 0; // Height of the offscreen graphics MemoryImageSource source = null; // View is calcaulated here before dispaly public Viewer() { // use PixelGrabber to read pixels data into // idata array init(); } public void init() { // some init code idata = readImagePixelData(imageFileName); } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { // Setup offscreen rendering environmnent offwidth = getWidth(); offheight = getHeight(); offImage = createImage(offwidth, offheight); offGraphics = offImage.getGraphics(); vdata = new int[vwidth * vheight]; source = new MemoryImageSource(vwidth, vheight, vdata, 0, vwidth); source.setAnimated(true); view = createImage(source); // read pixel data from idata and // use some warp transform to // extract a new view according // to user input transform(idata, vdata, mouse_x, mouse_y); source.newPixels(); offGraphics.drawImage(view, 0, 0, this); g.drawImage(offImage, 0, 0, this); } === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Expanding a shape
You can use the Area class to add in the original Shape: public Shape expandShape(Shape s, float d) { BasicStroke bs = new BasicStroke(d); // or new BasicStroke(d, CAP_ROUND, JOIN_ROUND); Area a = new Area(bs.createStrokedShape(s)); a.add(new Area(s); return a; } Note that the JOIN setting by default is MITER which may not match your expectations for what it means to expand the boundary of a Shape. ROUND would result in a smoother resulting outline... ...jim Chris Nokleberg wrote: I'd like to expand the boundary of an arbitrary Shape. If I use a BasicStroke createTransformedShape, the result is perfect except for the resulting hole. I currently get rid of the hole by iterating over the path, splitting the shape into multiple subshapes, and then comparing the bounds of each subshape to find the outermost one. This is bunch of work just to undo the unnecessary work BasicStroke has already done, though. Any suggestions on a cleaner solution? Thanks, Chris === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Expanding a shape
It depends on the performance you are looking for. One situation where Area can take a fairly long time to perform its calculations is when you have curves that are very similar to each other - which would happen here if you had an expand distance that was very small - say much smaller than a pixel. But I'm imagining that the expand distances will typically be larger than a pixel so the calculations should be reasonable. Try it and see (and report back on the results)... ...jim Chris Nokleberg wrote: Thanks. Actually I forgot to mention that I previously had used Area but had some issues with performance. It seems like a bit of overkill for this problem, since the path of interest is already calculated as part of stroking. But I doubt there is a better solution unless I reimplement part of BasicStroke, which I'm not going to do :-) Thanks again, Chris p.s. This is for http://tonicsystems.com/products/viewer/ a free PowerPoint viewer which uses Java2D *very* heavily. Expanding a shape is necessary for shadowed+filled shapes with complex strokes (e.g. dashed or triple-line)--the cast shadow is as if the shape had a solid stroke. I assume MSFT did it that way because it was easier to implement, which made me think there might be some tricky fast way. On 7/17/06, Jim Graham [EMAIL PROTECTED] wrote: You can use the Area class to add in the original Shape: === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] How to do pixel based animation instead of MemoryImageSource?
Hi ylzhao, There are some missing details in your post that affect the type of solution that can achieve your goals. For instance, how often are the pixels updated as compared to how often the updated image is drawn to the screen? Also, what percentage of the pixels are modified on a typical update? Are the values of any of the pixels in the image read back during the modification phase? These issues matter since they can affect how much hardware acceleration can help you. For example, if your updates touch most of the pixels in the image, and they are read/modify/write types of updates, and you update the pixels once per frame rendered to the screen, then hardware acceleration will not give you much benefit and may actually hurt your performance as the read performance of most video cards is very poor compared to system memory. Unfortunately we are still working on a way to provide better acceleration-friendly access to the pixels of various image types. See the bug 6205557 for more information: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6205557 Right now if you get the DataBuffer from a Raster for a BufferedImage the image will become permanently non-acceleratable. This means that any of the relatively efficient methods on DataBuffer for updating the pixels are out of reach if you want to maintain acceleration. Using the data modification methods on the WritableRaster class will allow your image to remain acceleratable, but each time you modify the pixels it will take 2 copies to the screen before the copies become accelerated again. The reason the image is only accelerated on the second and subsequent copies is that the copy of the image data to the cached vram surface is unnecessary work if the image is always changing. Probably the best bet would be a solution based on an INT_RGB BufferedImage and modifying the pixels using the method: WritableRaster.setDataElements(x, y, int[]); ...jim In JDK 1.5, there are BufferedImage, VolatileImage and BufferStrategy which can be hardware accelerated. However, if operate on the pixel data buffer directly, Java 2D engine can't use hardware acceleration. So, my question is : Is there a method can produce pixel based animation and use hardware acceleration instead of MemoryImageSource? [Message sent by forum member 'ylzhao' (ylzhao)] === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Smooth Gradients
We currently only worry about dithering on 8-bit indexed destinations. We have a request outstanding for dithering on 15/16-bit displays, but we haven't gotten to it. This would be the first request for dithering on a TrueColor display. ;-) Presumably if you get it working for 15/16-bit then the same algorithm could be used for 24-bit? Not really, the dithering would be baked into the loop that did the conversion to and storage into the 15/16 bit destinations. In the case of the 15/16 bit destinations, you dither with a stochastic metric proportional to the 2 or 3 bits of the 8-bit original data that you are discarding. With 24-bit dithering we are already storing all of the source data that we maintain in any of our pipelines (which treat 24-bit xRGB or 32-bit ARGB as the most general intermediate formats) so it is not only an issue of new code to apply the stochastic noise, but also we would have to upgrade many pipelines to maintain more than 8 bits per component precision throughout our rendering code. That's a major upgrade across the board. It's actually not unreasonable to dither 24-bit images. High-end image processing for video and film is ... In those fields, yes, it is common to maintain better than 24-bit precision, but we haven't been designing for those fields (so far). 16-bit per component upgrades have been on our wish list for a while now, more for the alpha blending (and other image processing) accuracy than for the ability to dither a 24-bit image... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] dash lines
The CAP decoration is applied at the end of each dash as documented (though admittedly this phrase isn't repeated in the docs of the constructors, just the class comments and the constants). Thus, the round caps will eat into the null space of the dashes by half of the line width on both ends of each dash. Square caps will also eat into the null voids of the dash pattern. The net effect is that if you have a line width of 4 and a dash pattern of 4,4 and a CAP of: BUTT- lines look 4,4 dashed SQUARE - lines look continuous with no dashing ROUND - lines connect, but narrow between the dashes You are using a line width of 2 with the pattern of 4,4 and so the effect isn't as pronounced as those examples, but it still makes it look like the pattern has reduced null areas. The parts where it closes completely could be the rendering code trying to do something sensible with a circular shape that is only 2 pixels tall - which release and platform is that on? In any case, try the different values for CAP and you should see the dash open up or close more. If you then go back and modify your dash pattern to account for the fact that the CAPs are eating into the null space of the pattern you should be able to achieve the effect you are looking for. Also, ROUND caps with a line width of 2 doesn't leave much room for roundness. That is probably responsible for most of the inconsistency you see on the various angles. Try a line width of at least 3 for ROUND or use BUTT instead... ...jim Russell East wrote: Hi, the attached sample app uses Java2D dash pattern to try to create a railway pattern, but the result isn't very good. The code is specifying the dash array as { 4.0f, 4.0f } but I'm seeing variable results: o on the top line it seems more like {5, 3} o on the left line seems more like { 6, 2, 5, 3 } and o on the bottom line does not look dashed at all Is it something I'm doing wrong in my code, or known problem? -- Russell === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. /* * Copyright (C) 1999 - 2006 by Environmental Systems Research Institute Inc. * All Rights Reserved. * * N O T I C E * * THIS MATERIAL IS CONSIDERED A TRADE SECRET BY ESRI. * UNAUTHORIZED ACCESS IS PROHIBITED. * * $Workfile:$ $Revision:$ */ package com.esri.mc.app; import javax.swing.*; import java.awt.*; import java.awt.geom.GeneralPath; /** * dash lines look wrong */ public class RailwayLines extends JFrame { public static void main(String[] args) { new RailwayLines().setVisible(true); } public RailwayLines() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setBounds(200, 200, 500, 300); String text = System.getProperty(java.vm.version); this.setTitle(text); MyCanvas canvas = new MyCanvas(); this.getContentPane().add(canvas); } } final class MyCanvas extends JComponent { private Stroke topStroke, backStroke; private Color topColor, backColor; private GeneralPath path; MyCanvas() { topStroke = constructTopStroke(); backStroke = constructBackStroke(); topColor = Color.WHITE; backColor = new Color(102, 102, 102); path = constructPath(); } private GeneralPath constructPath() { GeneralPath path = new GeneralPath(); path.moveTo(100.0f, 100.0f); path.lineTo(200.0f, 200.0f); path.lineTo(400.0f, 200.0f); path.lineTo(400.0f, 100.0f); path.closePath(); return path; } private Stroke constructBackStroke() { float width = 4.0f; int cap = BasicStroke.CAP_ROUND; int join = BasicStroke.JOIN_ROUND; return new BasicStroke(width, cap, join); } private Stroke constructTopStroke() { float width = 2.0f; int cap = BasicStroke.CAP_ROUND; int join = BasicStroke.JOIN_ROUND; float miterLimit = 10.f; float[] dash = { 4.0f, 4.0f }; float dashPhase = 0.0f; return new BasicStroke(width, cap, join, miterLimit, dash, dashPhase); } protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; g2.setColor(backColor); g2.setStroke(backStroke); g2.draw(path); g2.setColor(topColor); g2.setStroke(topStroke); g2.draw(path); } } === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED]
Re: [JAVA2D] dash lines
A question though. Why should the choice of end cap be affecting the rendering of a line between the end points? IMO each dash should be unaffected by the cap, except for the dashes at each end of the line. Seems like an undesirable feature to me. It's not just Java - X11 (for OnOff dashes) and PostScript also do it this way. I haven't done a full survey of other packages, though... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] dash lines [ design suggestion ]
Unfortunately it would require a lot of work on the line stroking package. It was designed to apply stroking as a pre-filter before widening and decorations so the information on the endpoints gets lost in the process. File a feature request as I don't think we have anything like this in the database... ...jim Russell East wrote: Jim, now that I look at it, it would be more flexible if there were an additional parameter within the relevant BasicStroke constructor like this: public *BasicStroke*(float width, int cap, int join, float miterlimit, float[] dash, float dash_phase, int dash_cap) where dash_cap has same possible values as cap. With this in place, cap should apply only to the end-points, and dash_cap applies to the dashes themselves. -- Russell Russell East wrote: So I included the rendering hints like the following ones that are commented-out. AntiAliasing makes the dashes consistently { 6, 2 } and also fuzzies up the linework. Stroke_Pure doesn't seem to make any difference. Nope, having cap=BUTT is the workaround solution for me. A question though. Why should the choice of end cap be affecting the rendering of a line between the end points? IMO each dash should be unaffected by the cap, except for the dashes at each end of the line. Seems like an undesirable feature to me. -- Russell protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; //g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); //g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setColor(backColor); g2.setStroke(backStroke); g2.draw(path); g2.setColor(topColor); g2.setStroke(topStroke); g2.draw(path); } Jim Graham wrote: Other things to try would be STROKE_PURE and ANTIALIASING hints... ...jim Russell East wrote: Jim, thanks for the clarification. which release and platform is that on? both 1.5.0_07-b03 and 1.6.0-rc-b89 on Fedora Linux, as well as 1.6.0-beta2-b85 on Windows XP The context of this is that my real app is reading SVG and painting it using java2D. The svg code looks like this: use xlink:href='a_path' fill='none' stroke='rgb(102,102,102)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/ use xlink:href='a_path' fill='none' stroke='rgb(255,255,255)' stroke-dasharray='4,4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/ so you can see the svg itself is supplying the round for line cap. I expect that I will simply have to ignore it and use butt instead, or mess with the supplied dash pattern. Curiously enough, if I save one of these SVG drawings and re-display within Firefox, it has the exact same problem. -- Russell Jim Graham wrote: The CAP decoration is applied at the end of each dash as documented (though admittedly this phrase isn't repeated in the docs of the constructors, just the class comments and the constants). Thus, the round caps will eat into the null space of the dashes by half of the line width on both ends of each dash. Square caps will also eat into the null voids of the dash pattern. The net effect is that if you have a line width of 4 and a dash pattern of 4,4 and a CAP of: BUTT- lines look 4,4 dashed SQUARE - lines look continuous with no dashing ROUND - lines connect, but narrow between the dashes You are using a line width of 2 with the pattern of 4,4 and so the effect isn't as pronounced as those examples, but it still makes it look like the pattern has reduced null areas. The parts where it closes completely could be the rendering code trying to do something sensible with a circular shape that is only 2 pixels tall - which release and platform is that on? In any case, try the different values for CAP and you should see the dash open up or close more. If you then go back and modify your dash pattern to account for the fact that the CAPs are eating into the null space of the pattern you should be able to achieve the effect you are looking for. Also, ROUND caps with a line width of 2 doesn't leave much room for roundness. That is probably responsible for most of the inconsistency you see on the various angles. Try a line width of at least 3 for ROUND or use BUTT instead... ...jim Russell East wrote: Hi, the attached sample app uses Java2D dash pattern to try to create a railway pattern, but the result isn't very good. The code is specifying the dash array as { 4.0f, 4.0f } but I'm seeing
Re: [JAVA2D] Smooth Gradients
Here's a guess - you basically want the LSbit of the raster to have a regular pattern to it rather than be banded. If you don't want to reinvent the GradientPaint wheel, then you could write a delegating Paint implementation that used GradientPaint to generate an initial Raster and then filter its result into a new Raster to return as the answer. This would defeat the OpenGL accelerated GradientPaint code if you are using that pipeline, but it may minimize the effect of the banding. Now where you are getting a sudden shift from one gray level to another you would then be getting a subtle change in the LSbit dither pattern which may be less detectable by human eyes. int gpbuf[]; int mybuf[]; for (int y = 0; y h; y++) { int bits = y 1; bits = bits 8; bits = bits 16; // bits is 0x01010101 for odd rows and 0x0 for even for (int x = 0; x w; x++) { mybuf[myoffset+x] = gpbuf[gpoffset+x] ^ bits; bits ^= 0x01010101; } myoffset += myscan; gpoffset += gpscan; } ...jim Ben Galbraith wrote: Jim, Thanks for looking into this, and thanks to swpalmer for creating the test case. I realize why the bars appear, and sadly, they appear on the LCDs I've tested as well. Rather than try and get you guys to introduce new features into your rendering engine (dithering in a 24-bit environment, for example) I was hoping some graphics gurus could tutor me on how to create grayscale gradients of limited range that don't have banding problems. It sounds like from your last paragraph that I should try a different set of colors above 50% luminance? Ben On Jun 20, 2006, at 11:48 PM, Jim Graham wrote: When I run this case I can just make out 29 extremely faint bars on the screen which is exactly how many possible colors there are between the endpoints you chose so it looks like I am seeing adjacent colors on a true-color display. I'm a bit surprised that my eyes are that sensitive and that my LCD panels are that accurate (these are decent, but not top-of-the-line, monitors and often consumer LCD monitors don't really provide the full 256 shades of each color component so I guess I lucked out there). If you see it worse on other monitors (in particular, fewer than 29 bars across the window) then it may be that those aren't true 24-bit panels/displays. We currently only worry about dithering on 8-bit indexed destinations. We have a request outstanding for dithering on 15/16-bit displays, but we haven't gotten to it. This would be the first request for dithering on a TrueColor display. ;-) I agree that the problem is visible, but it is a lot less visible with colors and with other parts of the grayscale spectrum (you chose a band of 30 colors just below 50% luminance where it is most noticeable). It would be a fairly low priority for us to fix right now. Perhaps when we add support for 8bit per component image formats we might address issues like this. You might want to file a feature request on this so it doesn't get lost... ...jim [EMAIL PROTECTED] wrote: I was bored, so here's a test case... I can see the banding, just barely. I suppose some monitors will make it look worse than others. In any case I think the solution is dithering, but you will have to do it manually, simply supplying the rendering hint (g2.setRenderingHint (RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE); ) doesn't seem to have an effect on the behavior of GradientPaint. [code] /* * Gradient.java * * Created on June 5, 2006, 10:29 PM * */ package scott.palmer; import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; /** * * @author Scott Palmer */ public class Gradient extends JPanel { public static void main(String [] args) { JFrame f = new JFrame(Gradient with Banding issues); f.setContentPane(new Gradient()); f.setSize(800,200); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setPaint(new GradientPaint( 0,0,new Color(101,101,101), getWidth(),0,new Color (130,130,130))); g2.fillRect(0,0,getWidth(),getHeight()); } } [/code] [Message sent by forum member 'swpalmer' (swpalmer)] http://forums.java.net/jive/thread.jspa?messageID=119469 = == To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED
Re: [JAVA2D] KEY_STROKE_CONTROL, thanks
Sorry for the delay, I just noticed that no one answered this. Typically PURE means don't do anything to the path and NORMALIZE means tweak the values, which should mean that PURE would be faster, but the difference should be small as the tweaking is pretty minimal and done on a per path element basis. PURE should ideally mean that we shouldn't use platform renderers with integer coordinates to do the rendering. That would only really matter for cases like X11 and GDI which have integer APIs, and so this will matter less as we move forward with some more advanced APIs like OpenGL and D3D in the future. If/when we do look at that hint in choosing a pipeline then PURE would mean we would have to back off to software rendering for those older platform APIs and we might lose some hardware acceleration performance... ...jim Michele Puccini wrote: Hi Jim, thank you for the KEY_STROKE_CONTROL hint, which saved me from getting poor stroking/positioning quality expecially with small fonts. I think that this hint should be publicized a little more. I suppose that when KEY_STROKE_CONTROL is set to VALUE_STROKE_PURE it doesn't affect the performance of Java2D. Can you confirm this ? Cheers, Mik -- === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Smooth Gradients
When I run this case I can just make out 29 extremely faint bars on the screen which is exactly how many possible colors there are between the endpoints you chose so it looks like I am seeing adjacent colors on a true-color display. I'm a bit surprised that my eyes are that sensitive and that my LCD panels are that accurate (these are decent, but not top-of-the-line, monitors and often consumer LCD monitors don't really provide the full 256 shades of each color component so I guess I lucked out there). If you see it worse on other monitors (in particular, fewer than 29 bars across the window) then it may be that those aren't true 24-bit panels/displays. We currently only worry about dithering on 8-bit indexed destinations. We have a request outstanding for dithering on 15/16-bit displays, but we haven't gotten to it. This would be the first request for dithering on a TrueColor display. ;-) I agree that the problem is visible, but it is a lot less visible with colors and with other parts of the grayscale spectrum (you chose a band of 30 colors just below 50% luminance where it is most noticeable). It would be a fairly low priority for us to fix right now. Perhaps when we add support for 8bit per component image formats we might address issues like this. You might want to file a feature request on this so it doesn't get lost... ...jim [EMAIL PROTECTED] wrote: I was bored, so here's a test case... I can see the banding, just barely. I suppose some monitors will make it look worse than others. In any case I think the solution is dithering, but you will have to do it manually, simply supplying the rendering hint (g2.setRenderingHint(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE); ) doesn't seem to have an effect on the behavior of GradientPaint. [code] /* * Gradient.java * * Created on June 5, 2006, 10:29 PM * */ package scott.palmer; import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; /** * * @author Scott Palmer */ public class Gradient extends JPanel { public static void main(String [] args) { JFrame f = new JFrame(Gradient with Banding issues); f.setContentPane(new Gradient()); f.setSize(800,200); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setPaint(new GradientPaint( 0,0,new Color(101,101,101), getWidth(),0,new Color(130,130,130))); g2.fillRect(0,0,getWidth(),getHeight()); } } [/code] [Message sent by forum member 'swpalmer' (swpalmer)] http://forums.java.net/jive/thread.jspa?messageID=119469 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Smooth Gradients
Hi Ben, What is the ColorModel in the destination you are rendering to? What kind of device are you displaying on? Can you send a test case that demonstrates it? ...jim Ben Galbraith wrote: Hi all, I'm seeking to create a smooth gradient background for a JComponent that goes from RGB 101, 101, 101 to RGB 130, 130, 130. Of course, that's only 29 colors, and I'm getting some serious banding when the JComponent takes up a large space. Yet, increasing the color range doesn't meet my needs; the contrast between the dark and light is too harsh. Do I have any options for smoothing out the gradient? I don't know much about graphics, so I'm fumbling around in the dark on this one. Can I switch to some fancy color space that supports thousands of grays instead of just 256 shades? Am I meant to start dithering? Should I introduce some color into my gradient to increase the pool of colors interpolated into the gradient? Thanks! Ben === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Transparent pixels in PNG/Buffered Image
Does the dispose() call potentially flush some drawing operations? Is it simply not needed if you don't write to the graphics context? Jim would probably be a better person to answer this question, but since JDK 1.4 or so, Graphics.dispose() doesn't really do anything heavyweight; we have other internal mechanisms for ensuring that associated resources are disposed properly. It doesn't (currently) flush pending operations or anything like that, and nowadays it doesn't really matter whether you call it or not (it won't leak if you don't). That said... dispose is used to free internal resources associated with the contexts manually. As its documentation states, the finalizer will take care of those resources anyway, but more aggressive disposing will keep the resource usage minimal. Graphics, like most objects that might potentially include native data that needs to be disposed, protects itself with a finalizer to free the resources even if you forget to manually dispose it. Thus, dispose() is simply a more aggressive technique to keep overall resource usage down when you know that you are done with an object. So, from the two pieces of code, the one inside your paint routine which is probably going to be called a lot is probably the one to worry about disposing more than one you incidentally create during initialization, though ideally you would dispose both. It's just much more critical in code that might expect to be called hundreds of times per second (during a flurry of updates for instance). On a side note, in 1.4 we removed the need to dispose our regular graphics objects by moving all of their data into Java structures which can be garbage collected normally without any need for a finalizer. I'm not entirely sure about the Graphics objects used in printing, though, but all of the ones on the screen and on offscreen, volatile, and buffered images are all finalizer free. You shouldn't make a habit of relying on that, though, as I have no idea if any of the ports that other vendors make might not need have finalizable state in their graphics and so the dispose() method for them may have non-trivial meaning... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] A few simple Java 2D questions ...
No, by sub-pixel I mean geometry which places coordinates at fractional screen coordinates for purposes of expressing the locations of those vertices more accurately than integers would allow. If the display has sub-components that are smaller than a pixel, that could be taken advantage of during the rendering process as it is with LCD text, but that has nothing to do with the need that some applications have to express their geometry with sub-pixel precision. It may not seem obvious that sub-pixel precision in geometry matters when you are dealing with discreet pixels, but if you consider that antialiased rendering can show sub-pixel differences by the opacity of the pixels on the boundary of a shape, and if you consider that even with non-antialiased rendering the location of the jaggies on a sloped line will be affected by the sub-pixel location of the endpoints, you can start to see that allowing expression of coordinates more finely than an integer pixel location is worthwhile... ...jim [EMAIL PROTECTED] wrote: Hi Jim, By 'sub-pixel' are you referring to the sub-pixels in LCD displays, for example? Does this then not apply to CRT monitors? Thanks, D. [Message sent by forum member 'dodger' (dodger)] http://forums.java.net/jive/thread.jspa?messageID=116601 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Dithering
Hi Erik, There are likely 2 different issues that you are dealing with here. First is the issue of dithering during drawing vs. during imaging. We currently do dithering when rendering an image into a lower color resolution destination, but we don't do any dithering at all when we do draw and fill types of rendering. So, if you are using draw/fillGeometry(...) types of calls then you would be seeing thresholding of the solid color. This is something that we always meant to go back and fix, but there isn't much call for high quality rendering to low color resolution destinations in today's world of high memory and deep color displays. To force some dithering you could use a workaround to force the geometry calls to use imaging operations. One workaround would be to render to a higher color destination and then copy the high color image into the B/W destination using a drawImage(). That should force dithering. Another workaround would be to use a custom Paint which simply returns a raster containing a solid color. We currently implement Paint rendering as a series of imaging operations so that would invoke our dithering as well. You could use your own custom Paint or you could use a GradientPaint with both colors the same for example. A color with an alpha value of less than 1.0 (.f for float constructors or 254 for int constructors) might also trigger a slower dithering algorithm. On the other hand, even if you do use one of those workarounds, I'm afraid our dithering implementation is optimized more for a decent performance and acceptable quality compromise on 8-bit destinations than it is for lower color destinations. There isn't much call for rendering to lower color destinations these days given the wide prevalence of full color screens and imagery so this has been a low priority. The low priority of this type of rendering is perhaps reflected by the fact that I couldn't find any open bugs against this problem, though I know that anyone who would try to render into a monochrome image would run into this. Please submit a bug with some example code so that we can track the issue and provide a place for others to vote if they are affected by this problem as well... ...jim Erik Vanherck wrote: Hi, In a certain piece of code we were using Jai to dither a rendering of our chart objects, however this caused some performance issues and we noticed the RenderingHints.KEY_DITHERING so we tried moving the dithering into the rendering of the chart that was already using the graphics2D of a bufferedImage. While very performant, it doesn't yield the expected result. Instead of dithered it gives us a thresholded black and white image. I found very little information about the dithering hint while googling and searching the forums, except people asking how to turn it off ;-) Now my question is, should the pseudo code below work ? --- code snippet --- byte[] map = {(byte)0xFF, (byte)0x00}; final BufferedImage buf = new BufferedImage(Math.round(fWidth*scale), Math.round(fHeight*scale), BufferedImage.TYPE_BYTE_BINARY, new IndexColorModel(1,2,map,map,map)); final Graphics2D g2 = (Graphics2D)buf.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE); g2.scale(scale,scale); fChart.setGraphics2D(g2); fChart.render(); return buf; --- code snippet --- For reference we are using jdk 1.4.2_08 and any solution should work in java.awt.headless mode. Any feedback is highly appreciated Best regards, Erik - Erik Vanherck - Product Delivery Manager Inventive Designers Visit http://www.inventivedesigners.com Visit http://www.inventivedesigners.com/scriptura for Scriptura information ! Phone: +32 - 3 - 8210170 Fax: +32 - 3 - 8210171 Email: [EMAIL PROTECTED] Computers in the future may weigh no more than 1.5 tons. - Popular Mechanics, forecasting the relentless march of science, 1949 -- Inventive Designers' Email Disclaimer: http://www.inventivedesigners.com/email-disclaimer === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] getting pixel color information from a rectangle inside a Panel
Depending on the complexity of your drawing, simply rerendering the scene with the objects in the new position (with double buffering) may work well for 10 frames/second performance. Switch to using Swing with a JPanel (you'll have to override paintComponent instead of paint) and call repaint() every 100ms instead of drawing it directly. If your scene is complicated, though, then a layering solution as others have suggested can help with the performance... ...jim Thanasis (Hotmail) wrote: Hi to everyone, i have built a graphics application using only AWT. Inside a Panel i illustrate a graph which has a number of nodes and arcs (i have drawn THE GRAPH using g.fillOval and g.drawLine methods). What i want to achieve is to move a red node (circle) from one point P1 inside the Panel to another Point P2. I have done it as follows: .. while (P1!=P2){ draw the node in red color(fillOval) delay(100ms) draw the node in white color(fillOval) move P1 } The problem is that as the node is moving it ERASES any previous pixels lying below it. Is there any way to get the color of these pixels that lie below the moving node and DRAW IT ONLY if those pixels are white? Thanks in advance Thanasis === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] SampleModel.getDataElements()
I submitted bug 6369452: SampleModel and Raster methods do not specify the order of data in the array for multiple pixels to track this issue. It should appear in the bug parade in a day or two. Note that you can access the data a band at a time using the get/setSamples methods if that works better for you... ...jim Nidel, Mike wrote: I'm debugging some code that gets the sample values for pixels within a given rectangle, using SampleModel.getDataElements(int x, int y, int w, int h, Object obj, DataBuffer db) The API documentation is unclear on one point (or I'm missing it): the result is always pixel interleaved, regardless of the way the given DataBuffer is laid out. Perhaps this is exactly the purpose of this method, I have to admit that I haven't used it before, and I'm only reviewing code written by someone else. My question is just to clarify: getDataElements() as defined above will always return the interleaved samples for each pixel, correct? If so, in my case I think I should use DataBuffer methods instead. Just checking, thanks, Mike Nidel === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Problem with non-stopping calls to update()
Several of your images have tags which identify them as animated images even though they only have one frame defined. All of them have a graphics extension block listing a non-zero animation frame delay which implies that they are multi-frame GIF images with a delay between frames (40ms in most cases). wall_8.gif also has a NETSCAPE2.0 loop count tag defined which is another indicator that the image is animated. The repaints are our mechanism for getting you to render everything again when the next animated frame in the image you drew is ready - it is a result of the default implementation of the ImageObserver interface in this - the parameter you give to us as your ImageObserver. I would edit your images again and turn off all options related to anything to do with animation or multi-frame images - inter-frame delays, loop counts, etc. As an alternative you can convert them to PNG images which should work on 1.4 and later runtimes (actually as far back as 1.2 I believe)... ...jim --On Monday, August 29, 2005 2:05 PM +0200 Olof Bjarnason [EMAIL PROTECTED] wrote: Hi again java2d-list and Jim especially, OK I've tried to boil down the project as Jim suggested. At this stage, if I remove anything I can't seem to reproduce the problem. If you have interest enough to check it out, I am very thankful. First off, the Applet which shows the counts of updates, repaints and paints. Note after some seconds the update count and the paint count runs away - the mad-update behaviour: http://olofbjarnason.se/Terraformer/bin/Terraformer.html I've generated a javadoc tree, source code included: http://olofbjarnason.se/Terraformer/doc/index.html .. and also here is the source with resources: http://olofbjarnason.se/Terraformer/Terraformer.zip (compile: javac *.java in terraformer directory, run with Terraformer.html) Short project briefing: The Debug and GraphicsState classes are very small and have no graphics/AWT code at all. The Model class is purely logical - the simulation - it is quite big just skip checking it - it has no AWT code either. The important classes I should guess are TerraformerApplet and ResourceManager which do the AWT/graphics stuff, alone. ResourceManager uses a MediaTracker to load the images synchronously. Cya and thanks for you help, /Olof On 8/26/05, Jim Graham [EMAIL PROTECTED] wrote: We've probably exceeded the interest level of those here. The best thing at this stage would be to try to boil the test case down to the smallest case that still reproduces it (i.e. make a copy and start deleting/stubbing code while the problem still persists, etc.) and then send it to just me and I'll take a look at it off-line... ...jim --On Thursday, August 25, 2005 11:39 PM +0200 Olof Bjarnason [EMAIL PROTECTED] wrote: Is there any particular part of my source code you want me to post? Posting the whole project seems a bit too much for a mailing list... Thanks for your help, /Olof On 8/25/05, Jim Graham [EMAIL PROTECTED] wrote: Hi Olof, There is no hard requirement to use Swing. It does provide a number of features, such as automatic double buffering and Timers, which could save you some coding and debugging time, but it is also possible to roll your own as you have already done. Swing also provides a lot of features that you probably don't need in a web page game, though they shouldn't get in your way or hurt you. AWT is a lower level API, but still reasonably high level in the grand scheme of things (i.e. all of the GUI toolkits out there), so it is equally useful for your purposes... ...jim --On Thursday, August 25, 2005 8:37 PM +0200 Olof Bjarnason [EMAIL PROTECTED] wrote: OK since I've got you attention, please give me an educated answer to this: Should I use Swing exclusively for a web page game? Which version of the JRE Firefox-plugin is stable for end-users if I decide to use Swing instead of just ground-plate AWT? Thanks for your ideas, /Olof == === == To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help. === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Problem with non-stopping calls to update()
public void update(Graphics g) { // Background: map field g.drawImage(backbuffer, 0, 0, this); // Foreground: headsup display headsup.draw(g); } public void paint(Graphics g) { update(g); } Now the problem is that even though the window (Firefox or AppletViewer) is left unresized and nothing obscures it, the update-method gets called repeatedly without-end, giving less-than-optimal performance, and a lot of flickering. Are you calling repaint() from anywhere other than your frame update? Note that using this as the last parameter of g.drawImage() can lead to calls to repaint() since the default implementation of the ImageObserver in Component executes a call to repaint whenever more of the image is loaded from its source. However, this only happens for images loaded from a file or network connection, not images created with createImage(w, h) or new BufferedImage() (basically any image that you can render into which eliminates backbuffers) since those images are not loaded from a source image stream. Even more strangely, when starting the Applet, it works fine (update() gets called once a second..) for a some 5-10 seconds, then the mad update()-calling begins. I'm under WinXP, JRE1.4.2. The continuous update:ing really hogs the CPU (gets up to 90%) which is not good for a game supposed to be run on a web page while the user listens to music for example. Have you tried it with 1.5? Or one of the pre-release builds of 1.6? What happens right before the trigger? You could try overriding repaint() to see where it is coming from, but it is hard to get that information back out of the applet. You could see if the calls are going to paint() or update() by doing something like: update(Graphics g) { render(g, Color.blue); } paint(Graphics g) { render(g, Color.red); } render(Graphics g, Color trackcolor) { // the code from your current update() method // followed by: g.setColor(trackcolor); g.fillRect(0, 0, 10, 10); } Depending on the color of the square in the upper left you would know if this was the result of a call to update() (which means it came from a call to repaint() at some point) or if it was a call directly to paint() (which means it was handling some perceived damage to the window)... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Problem with non-stopping calls to update()
From the Component javadocs: The update method of Component calls this component's paint method to redraw this component. and: Subclasses of Component that override this method should either call super.update(g), or call paint(g) directly from their update method. OK, guess I misread the docs. Actually, I followed this tutorial to begin with: http://www.dgp.toronto.edu/~mjmcguff/learn/java/ either direction will work as long as you override both. Our docs show the guts in paint() and then update() redirecting to paint() since it reflects what would otherwise go on underneath the covers. Typically an animation program overrides paint() to start out with to draw a frame, because that is where a program should put its paint() code and that is where someone reading the code would go first to find the painting code. The override of update() is then added to stop the erase to background color flickering. When you look at it that way, it seems more logical to have the actual painting code in the paint() method, but both work as long as you override both. Of course, you've overridden update(), so this changes the behavior, but it's a bit confusing at the least. But there could be more wrong here: it could be that by changing the nature of update/paint interaction, you're getting in the way of the regular system of issuing and consuming repaint() events, which could cause the paint calls to keep being issued. The solution here is to simply override paint() and do your painting there. Or if you're using Swing, override paintComponent() instead. Don't override update, or at least not in the manner you are doing currently. I'm using AWT I guess, no Swing. I'm trying to go for old-API in order to make the game runnable on more computers. I compile for 1.4.2, but I guess 1.4.2 has Swing so I could go for paintComponent, but my feeling is I should use paint(), eg.the tutorial uses paint(). Comments? I don't see how the way you've overridden paint/update() can lead to the problem in and of itself. It would be an interesting experiment, but I wouldn't abandon your architecture to try to fix this. To improve performance in general: - use a timer to schedule regular repaints so you don't get swamped with constant repaint events (similar to what you're doing, but I don't follow the complexity of using key actions for this. Why not simply issue a repaint call?) This is a hard call. While I still need to think about the ramifications of what you've done with sending ActionEvents to yourself, simply using a Timer instead of rolling your own Thread would not change anything here if the action of the Timer was to send the ActionEvent. If you switched to periodic repaint() calls instead of sending an ActionEvent then it would mean that the calls to update() would happen directly instead of as a result of a frame update. You would either have to move the frame update code to the update() method, or you would have to have two timer events - one to update the frame, and another to call repaint - and the two would happen asynchronously. This points out a potential problem with the way you've written the code and could be the root cause of the flood of repaints. Are there ever any frames that take longer than 1 second to render? If so, then there is no inherent throttling of your ActionEvents to match the extended compute time. If, say, you have one frame update that takes 10 seconds to complete, then by the time it is done, there will be 10 ActionEvents in the queue waiting to be processed. If those events take less time to process then you will run through all 10 of them at once and see 10 updates very quickly in a row which could look like what is happening to you. If it is much more likely to encounter frame updates that take longer than 1 second then the backup will be constantly increasing. Instead of sending an ActionEvent every second which forces a frame update, you might want to have some way of creating back-pressure. Either: - have something in your frame update code which requests the subsequent frame when it is done and don't send another ActionEvent until it is requested - that guarantees a delay of N milliseconds between frames so if frames take longer than your delay, the ActionEvents don't accumulate. This is kind of hard to implement, though. - have your frame update code check the last time a frame was updated and if it was less than 1 second ago, skip this ActionEvent to catch up (another will come along in less than a second). - you can also look at the time-stamp of the ActionEvent and if it was sent more than 1 second ago, skip it in favor of one that you know will be coming along very soon. - have your frame update code increment number of frames handled and have the event sending code increment number of frames requested and if the requested count is too far ahead of the handled count (like more than
Re: [JAVA2D] Problem with non-stopping calls to update()
What happens right before the trigger? You could try overriding repaint() repaint() is not getting called excessively. It is only update() that gets called all the time. I know this since I tried this: public void repaint() { System.out.println(repaint); super.repaint(); } .. without repaint being printed every time update was printed (did the same thing for update() ) I don't understand this statement. Are you saying that update() was being called more times than repaint()? Also, note that there are several flavors of repaint() and any of them lead to update() being called... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.
Re: [JAVA2D] Problem with non-stopping calls to update()
: paint T=4036AWT-EventQueue-1: headsup.draw T=4076AWT-EventQueue-1: update T=4076AWT-EventQueue-1: paint T=4076AWT-EventQueue-1: headsup.draw T=4126AWT-EventQueue-1: update T=4126AWT-EventQueue-1: paint T=4126AWT-EventQueue-1: headsup.draw T=4136AWT-EventQueue-1: actionPerformed (by Swing-Timer) T=4136AWT-EventQueue-1: model.step T=4136AWT-EventQueue-1: updateBackbuffer T=4136AWT-EventQueue-1: repaint T=4136AWT-EventQueue-1: update T=4136AWT-EventQueue-1: paint T=4136AWT-EventQueue-1: headsup.draw T=4166AWT-EventQueue-1: update T=4166AWT-EventQueue-1: paint T=4166AWT-EventQueue-1: headsup.draw T=4206AWT-EventQueue-1: update T=4206AWT-EventQueue-1: paint T=4206AWT-EventQueue-1: headsup.draw T=4256AWT-EventQueue-1: update T=4256AWT-EventQueue-1: paint T=4256AWT-EventQueue-1: headsup.draw T=4296AWT-EventQueue-1: update T=4296AWT-EventQueue-1: paint T=4296AWT-EventQueue-1: headsup.draw T=4366AWT-EventQueue-1: update T=4366AWT-EventQueue-1: paint T=4366AWT-EventQueue-1: headsup.draw T=4406AWT-EventQueue-1: update T=4406AWT-EventQueue-1: paint T=4406AWT-EventQueue-1: headsup.draw T=4446AWT-EventQueue-1: update T=4446AWT-EventQueue-1: paint T=4446AWT-EventQueue-1: headsup.draw T=4487AWT-EventQueue-1: update T=4487AWT-EventQueue-1: paint T=4487AWT-EventQueue-1: headsup.draw T=4527AWT-EventQueue-1: update T=4527AWT-EventQueue-1: paint T=4527AWT-EventQueue-1: headsup.draw T=4577AWT-EventQueue-1: update T=4577AWT-EventQueue-1: paint T=4577AWT-EventQueue-1: headsup.draw T=4617AWT-EventQueue-1: update T=4617AWT-EventQueue-1: paint T=4617AWT-EventQueue-1: headsup.draw T=4657AWT-EventQueue-1: update T=4657AWT-EventQueue-1: paint T=4657AWT-EventQueue-1: headsup.draw T=4697AWT-EventQueue-1: update T=4697AWT-EventQueue-1: paint T=4697AWT-EventQueue-1: headsup.draw As you can see, the mad-updating begins at T=3205 and continues then on. Note that the actionPerformed from the Swing-Timer is still functioning, and that the method that keeps getting called is update (which in turn calls paint, which call headsup.draw). /Olof On 8/25/05, Olof Bjarnason [EMAIL PROTECTED] wrote: This is a very thourough answer. I will try to reply ... On 8/25/05, Jim Graham [EMAIL PROTECTED] wrote: From the Component javadocs: The update method of Component calls this component's paint method to redraw this component. and: Subclasses of Component that override this method should either call super.update(g), or call paint(g) directly from their update method. OK, guess I misread the docs. Actually, I followed this tutorial to begin with: http://www.dgp.toronto.edu/~mjmcguff/learn/java/ either direction will work as long as you override both. Our docs show the guts in paint() and then update() redirecting to paint() since it reflects what would otherwise go on underneath the covers. Typically an animation program overrides paint() to start out with to draw a frame, because that is where a program should put its paint() code and that is where someone reading the code would go first to find the painting code. The override of update() is then added to stop the erase to background color flickering. When you look at it that way, it seems more logical to have the actual painting code in the paint() method, but both work as long as you override both. I'm with you and I tried both, same result. Of course, you've overridden update(), so this changes the behavior, but it's a bit confusing at the least. But there could be more wrong here: it could be that by changing the nature of update/paint interaction, you're getting in the way of the regular system of issuing and consuming repaint() events, which could cause the paint calls to keep being issued. The solution here is to simply override paint() and do your painting there. Or if you're using Swing, override paintComponent() instead. Don't override update, or at least not in the manner you are doing currently. I'm using AWT I guess, no Swing. I'm trying to go for old-API in order to make the game runnable on more computers. I compile for 1.4.2, but I guess 1.4.2 has Swing so I could go for paintComponent, but my feeling is I should use paint(), eg.the tutorial uses paint(). Comments? I don't see how the way you've overridden paint/update() can lead to the problem in and of itself. It would be an interesting experiment, but I wouldn't abandon your architecture to try to fix this. I started porting my Applet to JApplet but it proved horrendously errorprone (basically had to cut
Re: [JAVA2D] Problem with non-stopping calls to update()
Hi Olof, There is no hard requirement to use Swing. It does provide a number of features, such as automatic double buffering and Timers, which could save you some coding and debugging time, but it is also possible to roll your own as you have already done. Swing also provides a lot of features that you probably don't need in a web page game, though they shouldn't get in your way or hurt you. AWT is a lower level API, but still reasonably high level in the grand scheme of things (i.e. all of the GUI toolkits out there), so it is equally useful for your purposes... ...jim --On Thursday, August 25, 2005 8:37 PM +0200 Olof Bjarnason [EMAIL PROTECTED] wrote: OK since I've got you attention, please give me an educated answer to this: Should I use Swing exclusively for a web page game? Which version of the JRE Firefox-plugin is stable for end-users if I decide to use Swing instead of just ground-plate AWT? Thanks for your ideas, /Olof === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message signoff JAVA2D-INTEREST. For general help, send email to [EMAIL PROTECTED] and include in the body of the message help.