Where exactly is the code? I don't see anything about image resizing here. Thanks, Strom
On Jan 15, 2:50 pm, Timothy Perrett <timo...@getintheloop.eu> wrote: > I've added the code here: > > http://github.com/dpp/liftweb/tree/wip_tim_285 > > Cheers, Tim > > On Jan 15, 8:52 pm, Ross Mellgren <dri...@gmail.com> wrote: > > > This is already on the main list, I moved it there after Peter mentioned > > it. Sorry, I have a bad habit of starting conversations on lift-committers > > I'm trying to break before David breaks it for me ;-) > > > GIF resizing was a huge sticking point for the project here at Paytronix > > that this code was originally written for. I'd prefer it if > > allresizetransforms couldresizeinto the same format as the source (right > > now it's GIF -> PNG, and most everything else is source type -> dest type), > > but: > > - Shrunk GIFs are ugly due to the limited color palette and single-bit > > transparency. > > - Calculating an ideal palette and doing any dithering is not trivial, > > and for the application I had it was fine to change the format. > > > -Ross > > > On Jan 15, 2010, at 3:47 PM, Jonathan Hoffman wrote: > > > > Hi Ross, > > > > That looks good. It seems you're doing a much better job of handling > > > gif than I would have. Maybe we should move this discussion to the > > > main list to get everyone's input on what features would be useful. > > > > Tim, If you've already created a branch, let me know and I'll get my > > > stuff in there too-- Myresizecode uses the sanselan project to read > > > exif orientation information. > > > > On Fri, Jan 15, 2010 at 10:33 AM, Ross Mellgren <dri...@gmail.com> wrote: > > >> Well, it has to keep the whole source (packed) in memory and the target > > >> (unpacked / 32 bit RGBA) in memory, so I would assume that as long as > > >> AffineTransformOp is not doing something untoward it's probably around > > >> (src width * src height * src bytes/pixel) + (dest width * dest height * > > >> 4 bytes) plus a little bit extra. > > > >> I'm not a Java2D guru or anything, so I'm not sure how that could be > > >> improved offhand. > > > >> If you want to wrap it up and put it in, that'd be awesome! > > > >> -Ross > > > >> On Jan 15, 2010, at 10:17 AM, Timothy Perrett wrote: > > > >>> Cool stuff Ross, whats the overhead like in terms of memory etc? > > > >>> I might have a bit of time to put this into a module and stuff it on > > >>> review board. > > > >>> Cheers, Tim > > > >>> On 15 Jan 2010, at 15:03, Ross Mellgren wrote: > > > >>>> According to Jon on the call, he said he was putting together just > > >>>> such a lift module (forimagestuff), so I figured I'd toss this over in > > >>>> case it was of use to him in that module. > > > >>>> If anyone else wants to use it independently, consider it a > > >>>> contribution to lift, and licensed the same way. > > > >>>> -Ross > > > >>>> On Jan 15, 2010, at 9:51 AM, Peter Robinett wrote: > > > >>>>> Ross, this looks nice. Imagine resizing code is something that I've > > >>>>> personally had to do many times and is always annoying, so perhaps > > >>>>> this would make a good Lift module? Anyway, this is probably best > > >>>>> discussed on the main list... > > > >>>>> Peter > > > >>>>> On Jan 14, 3:01 am, Ross Mellgren <dri...@gmail.com> wrote: > > >>>>>> Oh I nearly forgot I said on the conference call the other day that > > >>>>>> I'd send theimageresizecode we built at work, in case it would be > > >>>>>> helpful. Here it is: > > > >>>>>> import java.awt.{Graphics, RenderingHints, Transparency} > > >>>>>> import java.awt.geom.AffineTransform > > >>>>>> import java.awt.image.{AffineTransformOp, BufferedImage, ColorModel, > > >>>>>> IndexColorModel} > > > >>>>>> /** > > >>>>>> * Helpers for manipulating images > > >>>>>> */ > > >>>>>> object ImageHelpers > > >>>>>> { > > >>>>>> // Some code here omitted -- Ed. > > > >>>>>> /** Rendering hints set up for the highest quality rendering */ > > >>>>>> val highQualityHints = { > > >>>>>> val h = new RenderingHints(null) > > >>>>>> h.put(RenderingHints.KEY_ALPHA_INTERPOLATION, > > >>>>>> RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY) > > >>>>>> h.put(RenderingHints.KEY_COLOR_RENDERING, > > >>>>>> RenderingHints.VALUE_COLOR_RENDER_QUALITY) > > >>>>>> h.put(RenderingHints.KEY_INTERPOLATION, > > >>>>>> RenderingHints.VALUE_INTERPOLATION_BICUBIC) > > >>>>>> h.put(RenderingHints.KEY_ANTIALIASING, > > >>>>>> RenderingHints.VALUE_ANTIALIAS_ON) > > >>>>>> h.put(RenderingHints.KEY_RENDERING, > > >>>>>> RenderingHints.VALUE_RENDER_QUALITY) > > >>>>>> h > > >>>>>> } > > > >>>>>> // Some code here omitted -- Ed. > > > >>>>>> /** > > >>>>>> *Resizeanimageof the given source type by the given ratios, > > >>>>>> properly handling GIF transparency, giving back the resized > > >>>>>> *imageand the newimageformat type that should be used. > > >>>>>> * > > >>>>>> * Theimagetype might change if the input type is an indexed color > > >>>>>> model, because it is a hard problem to choose an optimized > > >>>>>> * palette, and currently we don't. This function will return > > >>>>>> "png" as the new type in this case. > > >>>>>> * > > >>>>>> * If the inputimageis not using an indexed color model with > > >>>>>> transparency, then the target format and color model will be > > >>>>>> * identical to the source. > > >>>>>> */ > > >>>>>> defresize(source: BufferedImage, inputFormat: String, dx: Double, > > >>>>>> dy: Double): (BufferedImage, String) = { > > >>>>>> var sourceColorModel = source.getColorModel > > >>>>>> val targetColorModel = source.getColorModel > > >>>>>> val standardColorModel = ColorModel.getRGBdefault > > > >>>>>> val (targetWidth, targetHeight) = (((source.getWidth: Double) > > >>>>>> * dx).asInstanceOf[Int], ((source.getHeight: Double) * > > >>>>>> dy).asInstanceOf[Int]) > > > >>>>>> defresize(src: BufferedImage, dst: BufferedImage) { > > >>>>>> val g = dst.createGraphics > > >>>>>> try { > > >>>>>> g.setRenderingHints(highQualityHints) > > >>>>>> g.drawImage(src, new > > >>>>>> AffineTransformOp(AffineTransform.getScaleInstance(dx, dy), > > >>>>>> AffineTransformOp.TYPE_BICUBIC), 0, 0) > > >>>>>> } finally { > > >>>>>> g.dispose > > >>>>>> } > > >>>>>> } > > > >>>>>> // GIF support in Java is very ornery. For GIFs we have to > > >>>>>> manually do the masking on input, and then just punt on outputting > > >>>>>> GIFs and instead output PNGs. > > >>>>>> if (sourceColorModel.isInstanceOf[IndexColorModel] && > > >>>>>> sourceColorModel.hasAlpha && > > >>>>>> sourceColorModel.getTransparency == Transparency.BITMASK && > > >>>>>> > > >>>>>> sourceColorModel.asInstanceOf[IndexColorModel].getTransparentPixel > > >>>>>> >= 0) { > > > >>>>>> val indexColorModel = > > >>>>>> sourceColorModel.asInstanceOf[IndexColorModel] > > >>>>>> val transparent = > > >>>>>> indexColorModel.getRGB(indexColorModel.getTransparentPixel) > > > >>>>>> val masked = new BufferedImage(standardColorModel, > > >>>>>> standardColorModel.createCompatibleWritableRaster(source.getWidth, > > >>>>>> source.getHeight), standardColorModel.isAlphaPremultiplied, null) > > >>>>>> var w = masked.getWidth > > >>>>>> var h = masked.getHeight > > > >>>>>> val buf = new Array[Int](w) > > > >>>>>> var y = 0 > > >>>>>> while (y < h) { > > >>>>>> source.getRGB(0, y, w, 1, buf, 0, 1) > > > >>>>>> var x = 0 > > >>>>>> while (x < w) { > > >>>>>> val c = buf(x) > > >>>>>> if (c == transparent) { > > >>>>>> buf(x) = 0 > > >>>>>> } > > >>>>>> x += 1 > > >>>>>> } > > > >>>>>> masked.setRGB(0, y, w, 1, buf, 0, 1) > > >>>>>> y += 1 > > >>>>>> } > > > >>>>>> val resized = new BufferedImage(standardColorModel, > > >>>>>> standardColorModel.createCompatibleWritableRaster(targetWidth, > > >>>>>> targetHeight), standardColorModel.isAlphaPremultiplied, null) > > >>>>>> resize(masked, resized) > > >>>>>> (resized, "png") > > >>>>>> } else if (sourceColorModel.isInstanceOf[IndexColorModel]) { > > >>>>>> // The input color model is indexed, and we know we won't > > >>>>>> be able to generate a tolerable palette to make another indexed > > >>>>>> color model, so use sRGB and upgrade to PNG. > > >>>>>> val resized = new BufferedImage(standardColorModel, > > >>>>>> standardColorModel.createCompatibleWritableRaster(targetWidth, > > >>>>>> targetHeight), standardColorModel.isAlphaPremultiplied, null) > > >>>>>> resize(source, resized) > > >>>>>> (resized, "png") > > >>>>>> } else { > > >>>>>> val resized = new BufferedImage(targetColorModel, > > >>>>>> targetColorModel.createCompatibleWritableRaster(targetWidth, > > >>>>>> targetHeight), targetColorModel.isAlphaPremultiplied, null) > > >>>>>> resize(source, resized) > > >>>>>> (resized, inputFormat) > > >>>>>> } > > >>>>>> } > > > >>>>>> } > > > >>>>>> It isn't perhaps the ideal implementation, as mentioned in some of > > >>>>>> the comments, but perhaps Jon or others might find it useful in > > >>>>>> whole or part. > > > >>>>>> -Ross > > >>>>> -- > > >>>>> You received this message because you are subscribed to the Google > > >>>>> Groups "Lift-committers" group. > > >>>>> To post to this group, send email to lift-committ...@googlegroups.com. > > >>>>> To unsubscribe from this group, send email to > > >>>>> lift-committers+unsubscr...@googlegroups.com. > > >>>>> For more options, visit this group > > >>>>> athttp://groups.google.com/group/lift-committers?hl=en. > > > >>>> -- > > >>>> You received this message because you are subscribed to the Google > > >>>> Groups "Lift" group. > > >>>> To post to this group, send email to lift...@googlegroups.com. > > >>>> To unsubscribe from this group, send email to > > >>>> liftweb+unsubscr...@googlegroups.com. > > >>>> For more options, visit this group > > >>>> athttp://groups.google.com/group/liftweb?hl=en. > > > >>> -- > > >>> You received this message because you are subscribed to the Google > > >>> Groups "Lift" group. > > >>> To post to this group, send email to lift...@googlegroups.com. > > >>> To unsubscribe from this group, send email to > > ... > > read more » -- You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.