Re: [JAVA2D] How to keep the rasterizer at bay when printing?
> Since (surprise) 'pdl' didn't help try 'raster', which is the opposite > of what you think is helpful but might be interesting. Thanks for the answer but I think the sarcasm is misplaced. Pease google "sun.java2d.print.pipeline" and see for yourself how much information you get. I could not find a list the possible values nor an explanation of what they do, only a hint that pdl might be a good idea. >> Furthermore it seems this decision reflects late 1990s thinking re. the >> capabilities and speed of some printers. Isn't it time to revisit? > > No, its the late eighties Microsoft APIs that limit what we can do. How do the MS APIs come into the picture? Unless we are talking about so-called Windows printers that render on the desktop and thus using GDI, I would not think they are involved. To be sure they are an important use case but they are not even the majority of printers. In any case the point is not just printers: you can "print" or "paint" to Graphics2D instances that generate PostScript, PDF, SVG or whatever and it is extremely unhelpful when they are sent a bitmap instead of the expected graphics instructions that you put in your code. There ought to be a switch to turn off rasterization *unconditionally* and ensure graphics command are sent exactly as they are written. As it is, the only way I could find to do that is to bypass the high-level print/paint methods and call paintCompoment and paintBorder directly. That works but then I have to perform nested widget placment, background printing etc manually, which is quite a bother. Is there a better way that I have overlooked? Regards, -- 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".
Re: [JAVA2D] How to keep the rasterizer at bay when printing?
Olivier Lefevre wrote: Since (surprise) 'pdl' didn't help try 'raster', which is the opposite of what you think is helpful but might be interesting. Thanks for the answer but I think the sarcasm is misplaced. Pease google "sun.java2d.print.pipeline" and see for yourself how much information you get. I could not find a list the possible values nor an explanation of what they do, only a hint that pdl might be a good idea. Well since this is internal implementation of the Sun JDK, and not in fact a standard property its not surprising its not documented. Its principle use is internal testing. Generating "PDL" graphics instructions ie NOT a rasterised bitmap is what the JDK does by default and strives to do whenever it can. So specifying PDL is either a no-op, or is possibly going to cause a failure at runtime since you are forcing an inappropriate path. Furthermore it seems this decision reflects late 1990s thinking re. the capabilities and speed of some printers. Isn't it time to revisit? No, its the late eighties Microsoft APIs that limit what we can do. How do the MS APIs come into the picture? Unless we are talking about so-called Windows printers that render on the desktop and thus using GDI, I would not think they are involved. To be sure they are an important use case but they are not even the majority of printers. I don't know what you are driving at. The standard way to print graphics on windows is via GDI, unless perhaps you are a .NET app, but even then I'll bet its translated into GDI under the covers as that's what the windows printer driver API wants. And GDI doesn't have an API to create a translucent color Color c = new Color(255,255,255,128); simply isn't available. So things like that force a bitmap but I am doubtful its relevant to your case : In any case the point is not just printers: you can "print" or "paint" to Graphics2D instances that generate PostScript, PDF, SVG or whatever and it is extremely unhelpful when they are sent a bitmap instead of the expected graphics instructions that you put in your code. There ought to be a switch to turn off rasterization *unconditionally* and ensure graphics command are sent exactly as they are written. As it is, the only way I could find to do that is to bypass the high-level print/paint methods and call paintCompoment and paintBorder directly. That works but then I have to perform nested widget placment, background printing etc manually, which is quite a bother. Is there a better way that I have overlooked? Ah! I suspect this is your application bug. Are you seeing this only when printing a Swing UI? How are you printing? Are you calling "component.paint(printerGraphics) on the printer graphics. Remember that Swing is double-buffered by default so it does all its painting to an off screen image and that "printerGraphics" for the printer sees only the resulting image. So its nothing to do with the printing implementation. You need to call Component.print() or Component.printAll() in which case Swing renders directly to the printer graphics. -phil. Regards, -- 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".
Re: [JAVA2D] What's a trick way to clamp a byte to 255 - 0? -- slowness fixed
All of this discussion happened while I was away on vacation. The code that came up was pretty much what I tend to use for clamping without branches, but there are a couple of things to note for this particular application: It's only valid for values that overflow in the range MININT=>511 and it only clamps to the output range 0=>255. The reason for the first constraint is that c<<23 only sets the high order bit if the overflow stays under 512. If you get up to 512 then the 9th bit is clear again and the "clamp to 255" part fails. (Though, it will also correctly clamp values between 768 and 1023 and every other 256-sized range of overflow values up to MAXINT - i.e. the ones that manage to have the 9th bit set...) The reason for the second constraint is because of the assumptions in how the math was constructed. The first constraint may not be a problem if the Cubic Interpolation values can never cause the value to sum up to 2x the maximum value for a component which is probably true, but depends on the cubic formula used to generate the interpolation coefficients (there are a few such formulas in common use) and so needs to be proven for a given formula. The second constraint doesn't seem like a problem if you are always dealing with 8-bit values which is very typical for today's computer graphics, except for one issue which has been ignored. The issue is that image interpolation should really be done in a premultiplied form - as should alpha compositing. The reason for this is that if you blend the 4 components (Alpha, R, G, and B) separately in a non-premultiplied form then a transparent pixel with a non-zero value in, say, its red component will contribute some red tinting to the final answer even though it was transparent and should not have contributed any energy in the first place. Java2D, for example, does linear and cubic interpolation internally in the premultiplied form in the Graphics2D implementation for this reason. Why is this an issue for the clamping equations? The reason is that if your accumulation values are premultiplied then the alpha component needs to be clamped to 0=>255, but the color components need to be clamped to the range 0=>alpha. The different range on the clamping of the color components means that the proposed equations won't work if you perform your calculations in the premultiplied form. What I've used instead is a sequence of operations that can clamp any input range to an arbitrary 0=>N output range as follows: c &= ~(c >> 31); c -= N; c &= (c >> 31); c += N; After the first line c is in the range 0=>MAXINT with all negative values mapped to 0. After the second line c is set up so that all valid values are in the range -N=>0 and all positive values are overflow values. After the third line all values are in the range -N=>0 with the positive values mapped to 0. After the fourth line all values are finally in the range 0=>N... (Also, I believe it uses the same number of ALU instructions as the c << 23) >> 31) | c) & ~(c>>31))&0xFF formula...) ...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] What's a trick way to clamp a byte to 255 - 0? -- slowness fixed
Jim, EXCELLENT! I need to do a couple of things then. 1) Check to see if the multiplication by the basis functions can possibly lead to the kind of values that can possibly cause the kind of overflow problems you describe. I think they might. 2) Generate a test case for the code you provided and post results. 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. The reason for the existence of my interpolator is that the primary function of my cylindrical panorama viewer is to project (the best I can) a cylindrical image into a rectified viewport. Interpolation before or after the projection simply doesn't work so the interpolator is integrated into the projection code. It would have been real nice to be able to hand off a chunk of the cylindrical image to a Java2D bi-cubic interpolator and get a nicely interpolated rectified viewport but that is impossible. The corners of the source image chunk are stretched in a non-linear fashion to fit the canvas. It's not a simple resize. But this is really interesting information. And maybe someday someone will ask me about it and I can sound smart... :-) Ken Jim Graham wrote: All of this discussion happened while I was away on vacation. The code that came up was pretty much what I tend to use for clamping without branches, but there are a couple of things to note for this particular application: It's only valid for values that overflow in the range MININT=>511 and it only clamps to the output range 0=>255. The reason for the first constraint is that c<<23 only sets the high order bit if the overflow stays under 512. If you get up to 512 then the 9th bit is clear again and the "clamp to 255" part fails. (Though, it will also correctly clamp values between 768 and 1023 and every other 256-sized range of overflow values up to MAXINT - i.e. the ones that manage to have the 9th bit set...) The reason for the second constraint is because of the assumptions in how the math was constructed. The first constraint may not be a problem if the Cubic Interpolation values can never cause the value to sum up to 2x the maximum value for a component which is probably true, but depends on the cubic formula used to generate the interpolation coefficients (there are a few such formulas in common use) and so needs to be proven for a given formula. The second constraint doesn't seem like a problem if you are always dealing with 8-bit values which is very typical for today's computer graphics, except for one issue which has been ignored. The issue is that image interpolation should really be done in a premultiplied form - as should alpha compositing. The reason for this is that if you blend the 4 components (Alpha, R, G, and B) separately in a non-premultiplied form then a transparent pixel with a non-zero value in, say, its red component will contribute some red tinting to the final answer even though it was transparent and should not have contributed any energy in the first place. Java2D, for example, does linear and cubic interpolation internally in the premultiplied form in the Graphics2D implementation for this reason. Why is this an issue for the clamping equations? The reason is that if your accumulation values are premultiplied then the alpha component needs to be clamped to 0=>255, but the color components need to be clamped to the range 0=>alpha. The different range on the clamping of the color components means that the proposed equations won't work if you perform your calculations in the premultiplied form. What I've used instead is a sequence of operations that can clamp any input range to an arbitrary 0=>N output range as follows: c &= ~(c >> 31); c -= N; c &= (c >> 31); c += N; After the first line c is in the range 0=>MAXINT with all negative values mapped to 0. After the second line c is set up so that all valid values are in the range -N=>0 and all positive values are overflow values. After the third line all values are in the range -N=>0 with the positive values mapped to 0. After the fourth line all values are finally in the range 0=>N... (Also, I believe it uses the same number of ALU instructions as the c << 23) >> 31) | c) & ~(c>>31))&0xFF formula...) ...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". === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message
Re: [JAVA2D] What's a trick way to clamp a byte to 255 - 0? -- slowness fixed
The premultiplication problem will not be an issue for my little interpolator since I do not composite. But it would be for someone trying to use my interpolator for another purpose than what it was designed for. You said that you don't need have the premultiplication problem because you do not composite, but I wanted to be clear about the terminology here in case someone else comes across this thread. The premultiplied form should be used if you have alpha in the images, whether or not you composite. After reading your description it sounds like your images don't have or need alpha since you are simply doing panoramic stretching of opaque photographs, right? So, it's really the lack of an alpha channel which means that the premultiplied issue isn't applicable here, not the lack of "compositing"... ...jim === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] How to keep the rasterizer at bay when printing?
> I could not find a list the possible values nor an explanation > of what they do, only a hint that pdl might be a good idea. It now occurs to me that PDL must stand for Page Description Language, i.e., just what I wanted but you say it's normally a no-op. > I don't know what you are driving at [with you remarks on Windows printers] I am vague on the architecture of Windows printing. I was hoping that in the case of "real" printers (i.e., with their own rasterizers) applications are talking directly to the printer driver that is installed with the printer, not to some generic Windows printer driver. If that's not the case maybe for high-quaklity printing you are better off generating PostScript and sending that directly to the printer? A few printers also understand PDF. > Are you seeing this only when printing a Swing UI? How are you printing? Yes, I was printing a JPanel with plots in it, i.e., just text ad line art but with some transparency. > Are you calling "component.paint(printerGraphics) on the printer graphics. No I was calling print and I even turned off Swing buffering manually but I was still getting bitmaps. However now that you told me that print never rasterizes I went back and I realized the problem is that a sub-widget was doing its own buffering for performance reasons and I was not turning off _that_. It seems to work fine now. Thanks! While we are talkinmg, I have a subsidiary question. When printing or saving to file the print size is not necessarily what is shown on the screen. One can simply apply a scaling transform to the graphics object or one can keep around a private, non-displayable copy of the widget and resize that one before printing it. The first solution is simpler but are there any gotchas with rescaling that I am not aware of? Regards, -- 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".
Re: [JAVA2D] How to keep the rasterizer at bay when printing?
Olivier Lefevre wrote: I could not find a list the possible values nor an explanation of what they do, only a hint that pdl might be a good idea. It now occurs to me that PDL must stand for Page Description Language, i.e., just what I wanted but you say it's normally a no-op. I don't know what you are driving at [with you remarks on Windows printers] I am vague on the architecture of Windows printing. I was hoping that in the case of "real" printers (i.e., with their own rasterizers) applications are talking directly to the printer driver that is installed with the printer, not to some generic Windows printer driver. If that's not the case maybe for high-quaklity printing you are better off generating PostScript and sending that directly to the printer? A few printers also understand PDF. Postscript also doesn't support translucency except in some unlikely and esoteric implementations and whilst windows provides a way to see if a printer is a postscript one it provides no such API for determining if its a PDF printer. Are you seeing this only when printing a Swing UI? How are you printing? Yes, I was printing a JPanel with plots in it, i.e., just text ad line art but with some transparency. Are you calling "component.paint(printerGraphics) on the printer graphics. No I was calling print and I even turned off Swing buffering manually but I was still getting bitmaps. However now that you told me that print never rasterizes I went back and I realized the problem is that a sub-widget was doing its own buffering for performance reasons and I was not turning off _that_. It seems to work fine now. Thanks! While we are talkinmg, I have a subsidiary question. When printing or saving to file the print size is not necessarily what is shown on the screen. One can simply apply a scaling transform to the graphics object or one can keep around a private, non-displayable copy of the widget and resize that one before printing it. The first solution is simpler but are there any gotchas with rescaling that I am not aware of? I can't say what you are not aware of until you tell me everything you are aware of. Image rescaling will work but be blurry like you complained about to begin with. One common mistake is to assume that text scales linearly from screen to printer. It doesn't. If you scale the graphics 4x then a specific piece of text might scale by 3.87 or 4.23, or 3.95 , or .. you can only measure text in the right context. So code that supports printing of a layed out component needs to use the screen FontRenderContext for the text. -phil. Regards, -- 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".