Re: [JAVA2D] createCompatibleImage: why is it faster than creating a Buffered image?

2009-06-10 Thread Jim Graham
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?

2009-06-10 Thread Jim Graham

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?

2009-06-08 Thread Jim Graham

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

2009-05-21 Thread Jim Graham
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?

2009-04-14 Thread Jim Graham
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

2009-03-24 Thread Jim Graham
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?

2009-02-18 Thread Jim Graham
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?

2009-01-20 Thread Jim Graham

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?

2009-01-20 Thread Jim Graham
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?

2009-01-20 Thread Jim Graham
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

2009-01-13 Thread Jim Graham
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

2008-12-02 Thread Jim Graham
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

2008-12-02 Thread Jim Graham
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

2008-11-25 Thread Jim Graham

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

2008-11-19 Thread Jim Graham
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

2008-11-17 Thread Jim Graham
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 ?

2008-10-06 Thread Jim Graham
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

2008-09-23 Thread Jim Graham
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

2008-09-23 Thread Jim Graham

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?

2008-09-18 Thread Jim Graham

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

2008-09-18 Thread Jim Graham
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

2008-09-18 Thread Jim Graham
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?

2008-09-17 Thread Jim Graham

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

2008-09-09 Thread Jim Graham

[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

2008-09-09 Thread Jim Graham
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()

2008-09-02 Thread Jim Graham

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?

2008-08-25 Thread Jim Graham

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?

2008-08-25 Thread Jim Graham

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()

2008-08-14 Thread Jim Graham

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

2008-08-13 Thread Jim Graham
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

2008-08-07 Thread Jim Graham

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

2008-08-06 Thread Jim Graham

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

2008-08-01 Thread Jim Graham

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

2008-08-01 Thread Jim Graham
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.....

2008-07-25 Thread Jim Graham
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

2008-07-21 Thread Jim Graham
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?

2008-05-27 Thread Jim Graham
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...

2008-05-19 Thread Jim Graham
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...

2008-05-19 Thread Jim Graham

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...

2008-05-19 Thread Jim Graham

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...

2008-05-13 Thread Jim Graham

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...

2008-05-13 Thread Jim Graham

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?

2008-04-15 Thread Jim Graham

[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?

2008-04-15 Thread Jim Graham

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

2008-03-04 Thread Jim Graham
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?

2008-01-14 Thread Jim Graham
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

2008-01-14 Thread Jim Graham
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

2008-01-14 Thread Jim Graham
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

2007-10-24 Thread Jim Graham

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

2007-10-12 Thread Jim Graham

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

2007-10-12 Thread Jim Graham

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?

2007-09-20 Thread Jim Graham

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?

2007-09-20 Thread Jim Graham

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?

2007-09-11 Thread Jim Graham

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

2007-08-24 Thread Jim Graham

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

2007-07-27 Thread Jim Graham

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

2007-07-24 Thread Jim Graham

[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?

2007-07-24 Thread Jim Graham

[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

2007-07-24 Thread Jim Graham

[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

2007-07-24 Thread Jim Graham

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

2007-07-24 Thread Jim Graham

[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

2007-07-19 Thread Jim Graham

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

2007-07-19 Thread Jim Graham

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

2007-07-19 Thread Jim Graham

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

2007-07-03 Thread Jim Graham

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

2007-06-29 Thread Jim Graham

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

2007-05-22 Thread Jim Graham

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

2007-05-07 Thread Jim Graham

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()...

2007-04-10 Thread Jim Graham

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()...

2007-04-09 Thread Jim Graham

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

2006-12-28 Thread Jim Graham

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

2006-11-29 Thread Jim Graham

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

2006-11-07 Thread Jim Graham

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

2006-08-22 Thread Jim Graham

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

2006-08-22 Thread Jim Graham

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

2006-08-07 Thread Jim Graham

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

2006-08-07 Thread Jim Graham

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?

2006-07-24 Thread Jim Graham

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

2006-07-17 Thread Jim Graham

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

2006-07-17 Thread Jim Graham

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?

2006-07-17 Thread Jim Graham

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

2006-07-10 Thread Jim Graham

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

2006-06-28 Thread Jim Graham

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

2006-06-28 Thread Jim Graham

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 ]

2006-06-28 Thread Jim Graham

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

2006-06-24 Thread Jim Graham

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

2006-06-20 Thread Jim Graham

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

2006-06-20 Thread Jim Graham

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

2006-06-05 Thread Jim Graham

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

2006-06-01 Thread Jim Graham

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 ...

2006-05-30 Thread Jim Graham

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

2006-05-11 Thread Jim Graham

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

2006-03-27 Thread Jim Graham

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()

2006-01-05 Thread Jim Graham

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()

2005-08-29 Thread Jim Graham

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()

2005-08-25 Thread Jim Graham

  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()

2005-08-25 Thread Jim Graham

 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()

2005-08-25 Thread Jim Graham

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()

2005-08-25 Thread Jim Graham
: 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()

2005-08-25 Thread Jim Graham

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.


  1   2   >