I bet we can meet or beat Cairo; I've never found Cairo to be terribly fast.
But of course one doesn't know until one tries.
Given that the main issue is really interpolation, it (and some of the
refactoring that's currently under discussion) seems relevant. There's some
work brewing on a new version of Grid, and being able to do this performantly
and easily can become a goal there. Grid already has more interpolation
options than Cairo does.
--Tim
On Thursday, August 07, 2014 01:41:39 AM Andrei wrote:
> @Andreas: thanks and sorry for late reply.
>
> Using your code, I created testable function that works almost 10x times
> faster then my naive implementation! Right now, though, it rotates image 90
> degrees to the left for some reason I don't really understand, but I
> believe it's fixable.
>
> Here's a code for (not fully correct) function:
>
> function imresize_cairo(dat::Array{Uint32, 2}, new_size::(Int, Int))
> cs = CairoImageSurface(dat, 0)
> new_dat = zeros(Uint32, new_size)
> new_cs = CairoImageSurface(new_dat, 0)
> pat = CairoPattern(cs)
> pattern_set_filter(pat, Cairo.FILTER_BILINEAR)
> c = CairoContext(new_cs)
> h, w = size(dat)
> new_h, new_w = new_size
> scale(c, new_h / h, new_w / w)
> set_source(c, pat)
> paint(c)
> return new_cs.data
> end
>
>
> I'm pretty satisfied with this version (or what it should turn into) both -
> because of its speed and possibility to use different interpolation
> schemas. Though, one disadvantage of using it in public package like
> Images.jl is that it brings additional dependency, and we all know how
> annoying these dependencies may be sometimes. We could implement 2 versions
> - one with Cairo and fast and another simple and slow - and then load
> appropriate function via macros. But since simple version doesn't support
> interpolation other than bilinear, we will have to restrict Cairo version
> to this type too to keep same interface. Or we can just 2 different
> functions, but it may be pretty confusing for new users.
>
> Some opinions on a better approach would be helpful here.
>
>
>
>
> On Tue, Aug 5, 2014 at 11:24 AM, Andreas Lobinger <[email protected]>
>
> wrote:
> > An example looks like this:
> >
> > using Cairo
> >
> > # prepapration, an image of 2x2 pixels, an target of 8x8 pixels
> >
> > d = [8 4; 2 1];
> > d0 = reinterpret(Uint32,d);
> > cs0 = Cairo.CairoImageSurface(d0,0); # 0 as FORMAT_ARGB32
> > show(cs0.data)
> > print('\n')
> >
> > d2 = zeros(Uint32,8,8);
> > cs2 = Cairo.CairoImageSurface(d2,0);
> >
> > p = Cairo.CairoPattern(cs0);
> >
> > # just scale by using FILTER_NEAREST
> >
> > pattern_set_filter(p,Cairo.FILTER_NEAREST);
> > c = Cairo.CairoContext(cs2);
> > scale(c,4,4);
> > set_source(c,p);
> > paint(c);
> > show(cs2.data)
> > print('\n')
> >
> > # now interpolate
> >
> > d3 = zeros(Uint32,8,8);
> > cs3 = Cairo.CairoImageSurface(d3,0);
> >
> > pattern_set_filter(p,Cairo.FILTER_GOOD);
> > c = Cairo.CairoContext(cs3);
> > scale(c,4,4);
> > set_source(c,p);
> > paint(c);
> > show(cs3.data)
> > print('\n')
> >
> > and gives on my command line:
> >
> > julia> include("ca.jl")
> > Uint32[8 2
> >
> > 4 1]
> >
> > Uint32[8 8 8 8 2 2 2 2
> >
> > 8 8 8 8 2 2 2 2
> > 8 8 8 8 2 2 2 2
> > 8 8 8 8 2 2 2 2
> > 4 4 4 4 1 1 1 1
> > 4 4 4 4 1 1 1 1
> > 4 4 4 4 1 1 1 1
> > 4 4 4 4 1 1 1 1]
> >
> > Uint32[3 4 4 3 2 1 1 0
> >
> > 4 6 6 5 3 2 1 1
> > 4 6 6 5 3 2 1 1
> > 4 5 5 4 3 2 1 1
> > 3 4 4 3 2 1 1 0
> > 2 3 4 3 2 1 0 0
> > 2 3 3 2 1 1 0 0
> > 1 2 2 1 1 0 0 0]
> >
> > But this is just how to handle the data. For interpreting the pixels
> > correctly you need to read little bit about the colormodel and pixel
> > formats.
> >
> >
> > Wishing a happy day,
> >
> > Andreas