Re: A request for future gdk_scale_pixbuf...



[ Let me start off by saying, that gdk_pixbuf_scale/composite
  is one of the API's I've done I'm more ashamed of - thee
  is no excuse for a function call with 17 arguments like
  gdk_pixbuf_composite_color() ]

"Lewin A.R.W. Edwards" <larwe larwe com> writes:

The current function doesn't operate very intuitively, and it's
ambiguous as to what exactly happens to the source pixbuf.

What I mean by this is that :

a) the idea of scaling by separate x,y scale factors and translating
the image isn't exactly what I'm used to from other OSs, plus it
introduces floating-point inaccuracy worries.

and

b) the API documentation, as written, implies that the function
actually reallocates the source pixbuf and changes the pixels inside
it. I am guessing that it really just reads the source pixbuf line by
line and performs an implicit transformation before blitting the
result to the destination pixbuf, but that's not what the
documentation says :)

Hmm, I would never have read it that way, but that's why
you have people other than the person writing the docs read
them :-)

It's admittedly a somewhat abstract / mathematical description;
and example in the docs would almost certainly help.

I was hoping that it worked like the drawing code in (say) OS/2, where
you specify a source rect within the source bitmap and a destination
rect within the destination bitmap. That way, everything is always an
integer.

This simply doesn't work.  A typical usage of gdk_pixbuf_scale() for
rendering a source pixbuf, scaled at some location at the destination
pixbuf. As a simple case, I have a 200x100 source image and I want to
render it at +100+100 with a size of 300x100.

This seems to fit your API exactly - but - in order to handle things
like exposes, I also will need to be able to render subparts of the
destination image. So, say that I need to render the portion of the
destination image at +300+100 100x100. What's the corresponding source
region of the image? +133.3333..+0 66.6666...x100

And no, rounding off here doesn't work at all - it's will produce
different results, and it's _very_ obvious if you expose part of an
image and what is exposed is slightly different than the original.

So, you'd need at a minimum, floating point coordinates for source and
dest rects. But in terms of keeping inaccuracy from creeping in when
rendering subportions, I felt it was better to express the
overall operation as:

 * Transform the source image
 * render part of the result

Rather than combining the two steps. 

There are other ways of expressing the transform - than 
the scale_x, scale_y, offset_x, offset_y I used - probably
a better would have been to have expressed it as via
the x/y/width/height the entire source pixbuf has in the
destination pixbuf under the transform.
 
I guess it's possible to wrap the function to get the behavior I
desire, but I'm still working with trying to understand how it works :/

To scale the image at src.{x,y,width,height} to 
dest.{x,y,width,height}, first we scale the image by
dest.width / src.width ; dest.height / src.height, putting
our target region at:

 src.x * dest.width / src.width, 
 src.y * dest.height / src.height

then we offset by

 dest.x - src.x * dest.width / src.width 
 dest.y - src.y * dest.width / src.width 
 
So, that the source region ends up at dest_x, dest_y. 

So, to summarize, for unclipped rendering: 

 scale_x = dest.width / src.width
 scale_y = dest.height / src.height
 offset_x = dest.x - src.x * dest.width / src.width 
 offset_y = dest.x - src.y * dest.width / src.width 
 dest_x = dest.x
 dest_y = dest.y
 dest_width = dest.width
 dest_height = dest.height

If you want to render only a portion of the result,
then dest_x,y,width,height are modified, 
scale_x,scale_y,offset_x,offset_y are left the same.

Regards,
                                        Owen

[ Havoc promises to try to extract docs from this somewhat 
  rambling email ]



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]