Marc, himself, his blogs, and you reading them.

November 30, 2005
My Ugly Hack at Java Image Resizing.

Ok, so I have done quite some Java, but most of that has been quite exclusively been pulled around the technical gravity centers Web, XML and derivatives... together with some more generic interest in sound OO design and patterns.

And yeah, I've been doing some image processing with The Gimp, which offers me some early understanding of the underlaying colormodels, transparency, unmask sharpness, feathers and antialliasing...

But when my home project to get a picture-album for daisy includes programmatic image resizing in Java I'm pretty much left to whatever the GoogleHarvest will bring me...

capetown-sa.jpg

When starting-off with the standard code-samples rescaling an image from 1600px width to 200px (still quite big for a thumbnail) I wasn't quite pleased with the result of the built in interpollation (even when set to 'bicubic' proclaimed as ensuring the better quality)

    public static BufferedImage scale(double scale, BufferedImage srcImg)
    {
        RenderingHints hints = new RenderingHints(null);
        hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        hints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
//        hints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        
        BufferedImage target = new BufferedImage((int)(srcImg.getWidth()*scale),
                                                                      (int)(srcImg.getHeight()*scale), 
                                                                      BufferedImage.TYPE_INT_RGB);
        
        Graphics2D g = target.createGraphics();
        g.drawImage(srcImg, null, null);
         
        AffineTransform affineTransform = AffineTransform.getScaleInstance(scale, scale);
         
        g.setRenderingHints(hints);
        g.drawRenderedImage(srcImg, affineTransform);
        
        g.dispose();
        return target;
    }

More GoogleHunting showed me I wasn't alone in my frustration, but also revealed the best way to get better results was just to use the imagemagick 'convert' behind the scenes through some Runtime.exec(). Trying that out, and seeing the better quality (but slower processing) I was only left to believe the Java libs (Java2D or JAI for that mather) must be able to do the job as nicely...

j2d-capetown-sa-200.jpg

Digging in again I allowed to help myself with the more dirty groundwork.... and Hohoho, Lo and Behold: what do you think of this 2nd result? I find it far more acceptable then the first for sure.

But don't jump up and down yet though, since here is my hack:

        double fScale = Math.min(scaleX, scaleY);
        
        // hack to go into things step by step, 
        // slows down but avoids bad quality from doing all in one step
        while (fScale < 0.5f)
        {
            imgSrc = scale(0.5f, imgSrc);
            fScale *= 2;
        }
        
        return scale(fScale, imgSrc);

So, I'm puzzled. And not sure what is ugglier (the first image result or the latter code) The recursive re-size in steps hack isn't one I like since it's far more costly then to do it in one sweap (but not really worse then using imagemagick for the scale I need to cover here). Also, I would suspect every resize operation to degrade quality a bit, which only gets accumulated through this way of working. However a simple visual check on the resulting image kinda shows the opposite effect on actual image quality, so I'm really left to wonder how exactly the interpollation algorithms are sampling the image in the first place. (I really think they are sampling right next to the nearest point, rather then in the middle of the various nearest points, but would need to build me a good sample test image to assess that point) Any expert out there that can point out where I or the Java libs are missing the point or someone that has the ready made interpollation test-images up somewhere?

capetown-sa-thumbsmooth.jpg

update: Those in search of a solution should dig down to the comment from Andrey Akselrod. That gave me this final nice looking result without any awkward hack. Many thanks for sharing this, Andrey.

# Posted by mpo at 08:08 AM | Comments (5) | TrackBack (0)

November 29, 2005
E4X

XML API for Javascript (well, ecmascript): home | pdf

# Posted by mpo at 10:32 AM | Comments (0) | TrackBack (0)

November 22, 2005
Social DoS Attacks

Me late again at reading this enteresting coverage of "social denial of service attacks". Yeah it's mainly geeky terminology for something Belgian media would call filibusteren or anti-poltics but when you take the time to read it (and are geeky enough to bite through) you can see how the formal terminology helps at recognising the issue and naturally proposing some solutions.

Most important lesson in my head: It's all right to complain, but it shouldn't keep you from doing your part of the work to make things better. Or put differently: if you're smart enough to complain, then you don't have the right to hide behind incompetence to actually help out.

Other synapses firing associations over here:

  • I've been reading up lately on some writings of Etienne Vermeersch lately. In one of the paragraphs of this article (all dutch) he mentions the tension between the happiness of the (uncaught) vilain and the misery of the good
  • This absolute claim pro personal rights (dutch again) that is so deceivingly smart written down that I'ld almost forget that it's completely missing out on my reaility-test. "To me, on a human-to-human level, not the theoretical rights (or the arguments to claim those) are of interest, but what you are going to do with them!"
  • The new apparent fashion wave of no value added comment writers attracted by slight political statements on Flemish blogs...
  • ... as well as the continued climate of possible national strikes over here in Belgium. I'ld really wish the unions could be creative enough to come up with some actual useful society-work their militants could be doing next time they mobilise them again. Not going to work would be a more valuable complaint to me if they could use the time gained to actually make a positive statement somewhere in stead.
# Posted by mpo at 02:58 PM | Comments (1) | TrackBack (0)

November 17, 2005
No, sorry, not my style...

A person like me who stubornly wants to dwell around in a world full of shiny happy people easily gets a rather unpleasant wake up call when receiving this:

Received: from EMEAEXCH01.tridion.local ([10.1.2.1]) by smtp1.tridion.local with Microsoft SMTPSVC(6.0.3790.1830);
	 Thu, 17 Nov 2005 19:08:12 +0100
Received: from nl1exch02.tridion.local ([10.100.2.1]) by EMEAEXCH01.tridion.local with Microsoft SMTPSVC(6.0.3790.1830);
	 Thu, 17 Nov 2005 19:08:11 +0100

Subject: Finding out more against Plone
Date: Thu, 17 Nov 2005 19:08:11 +0100

Marc,

It was good meeting you at the Belgium MarketShare event on September
30th - and good to talk about our times with {some internet startup company
he worked for and my former employer bought stuff from ages ago, never met him 
then}. I hope you did get a chance to pass on my regards to {dear friend 
that was his colleague for a while}.

I contact you this time in the home that you can do me a favour which I
can hopefully return it later.

We have a situation in one of our international countries where they are
asking us to compare Tridion versus against an open source CMS called
Plone.

This surprises me since we rarely compete with Open Source, but there
you are.

I'm looking for any doubts, uncertainties, fears there are about using
it.  I do not know how DAISY compares
with it, but its just the fears, troubles of Plone I would like to focus on.

Let me know if you can help - {his name}

{his sig}

Apart from just jotting this down in a blog here (basically cause I'm just eternally dumbfounded by this message) this message is making me do the following things:

  1. Silently wishing Plone all the best on this one. Hoping they're not just on the shortlist as the fishing bait to make the commercial vendors push prices down.
  2. Hope I can learn my kids to let them live quality lives in honest search for the good and the better of not only themselves. Winning is great, and something they should learn to strive for with an honest appetite, and enjoy plenty (and in appropriate modesty). But, please allow me to show them how to find pleasure in their own virtues rather then in other peoples vices or misfortune. Teaching them to make positive choices along the path, accepting how some of those don't turn out how they've meant it. Saying sorry now and then.
  3. Train my spamfilter.
# Posted by mpo at 10:11 PM | Comments (12) | TrackBack (0)

JNOS

Those #%@&@!&^ escapes again! Left a comment on Sylvain's recent outerhinking post, but noticed I forgot to escape all XML snippets in there... So redoing it on my own canvas here:

Well, probably only partly related, and I'm not trying to claim any visionary talents here, but his posting triggered a memory-synaps to an old misty posting.

I suspect that next in line sombody will want to straight-match a URL with patterns like this:

  • /jnos/session/xyz
  • /jnos/cont/*/xyz

To get a hold off an object 'xyz' (that is sitting in your session, or inside a continuation or apple where it maybe is being updated by a server side thread launched earlier... And behind the xyz/ could even folow a jxpath expression into the referenced object graph :-)

So in this light maybe this old idea of the 'object:' pseudo-protocol becomes usefull after all :-)

<map:match pattern="/jnos/**">
  <map:readobject src="object:{1}" />
</map:match>

The source contract could be tested for an subclassed to produce either an in vm java-object-ref (maybe even deserialized after getting it from some remote url?) or ready js-code to eval() as Sylvain was suggesting... I admit that part needs some more thinking...

Uh, no XML??? Yeah, that might sound like blasfemy to all the hardcore XMLizers in cocoon land, but we already have a <map:read> and <map:redirect-to> in cocoon that have nothing to do with XML... so, why not?

Like this I could still decide to have a <map:generate type="object" src="object:..." /> that would be the counterpart of the JNOSSerializer Sylvain hints about, and that could be used to still pull some xml representation of that object through a standard pipe towards portal, email, pdf and whatnot...

Just thoughts, you know.

# Posted by mpo at 05:09 PM | Comments (0) | TrackBack (0)

November 15, 2005
YEZZZZ!!!!

Since Flemish 'state' money started building this Meeting and Congres-centre in Bredene at the (old flemish proverbial getting badly translated "boogscheut") arc-shot from our doorstep the missus and me have been hoping there would be a decent cultural agenda for the place... We waited hopefully but heared nothing of that kind...

Last week we were even put on the wrong foot completely when the invitation for the opening showed a lot of references to more business oriented origanizations in stead (and oh, dispair: no mentioning of any cultural agenda) So we're glad to stand corrected to find their website show we can soon shop for concerts and plays just accross the street!

Being satisfied in my personal desires I'm even tempted to help boost their meeting and congress business now by showing the immense benefits this place has in its surrounding infrastructure as it's ideally placed within walking distance of

# Posted by mpo at 08:43 PM | Comments (3) | TrackBack (0)

November 10, 2005
as time passes
outerthoughttime.png # Posted by mpo at 10:56 PM | Comments (0) | TrackBack (0)