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