DrawImage with NearestNeighbor-Interpolation
-
Hello, does anyone know where I can find the function which maps the pixel coordinates from the source to the destination? I draw a (stretched) bitmap using
InterpolationMode.NearestNeighbor
andPixelOffsetMode.Half
onto a canvas and now want to know which pixel was mapped to a certain position - so that if I click with the mouse on that stretched pixel, I get the original coordinates. Thank you in advance! Alex -
Hello, does anyone know where I can find the function which maps the pixel coordinates from the source to the destination? I draw a (stretched) bitmap using
InterpolationMode.NearestNeighbor
andPixelOffsetMode.Half
onto a canvas and now want to know which pixel was mapped to a certain position - so that if I click with the mouse on that stretched pixel, I get the original coordinates. Thank you in advance! AlexNo I've never seen that function being available. However there are two simple solutions for what you seem to want: 1. the interpolation is quite simple, it basically is a linear re-scaling, something like:
xNew = x * scaleNew / scaleOld
and then the options determine the petty details. For one you need a floating point operation, and the result needs turned into an int again; that is where NearestNeighbor comes in (it basically means regular rounding: less than 0.5 becomes 0; 0.5 or more becomes 1). And PixelOffsetMode.Half means 0.5 is added anyways, so I would give this a try:
xNew = floor ((x+0.5) * floatScaleNew / floatScaleOld)
Caveat: one has to be careful with negative values, so when you run some tests, include both positive and negative values (unless negatives are irrelevant to your app). 2. As a big alternative you could simply use the function they use without having direct access to it; this is how it works: make a synthetic image, width=your original width, height=1; fill it with a wedge, i.e. the values 0, 1, 2, 3... etc. if it is a gray image; or perhalps (0,0,0), (1,1,1), (2,2,2), (3,3,3) if you prefer a regular RGB image (you may need a modulo-256 then). now let the system apply your scaling to it (in x direction), yielding a larger image with the same width as your actual scaled image. When you click the actual scaled image, use the mouse position and look into the scaled synthetic image; it will return a pixel value which equals the original x coordinate (or at least the lowest 8-bits of it if your synthetic is RGB). You can use the same trick in the other direction of course (i.e. there is no need to have a 2-D synthetic image). :)
Luc Pattyn [My Articles] Nil Volentibus Arduum
-
Hello, does anyone know where I can find the function which maps the pixel coordinates from the source to the destination? I draw a (stretched) bitmap using
InterpolationMode.NearestNeighbor
andPixelOffsetMode.Half
onto a canvas and now want to know which pixel was mapped to a certain position - so that if I click with the mouse on that stretched pixel, I get the original coordinates. Thank you in advance! Alex(this gibberish sentence has been necessary to get the message accepted by CP as it "appears to have already been posted") No I've never seen that function being available. However there are two simple solutions for what you seem to want: 1. the interpolation is quite simple, it basically is a linear re-scaling, something like:
xNew = x * scaleNew / scaleOld
and then the options determine the petty details. For one you need a floating point operation, and the result needs turned into an int again; that is where NearestNeighbor comes in (it basically means regular rounding: less than 0.5 becomes 0; 0.5 or more becomes 1). And PixelOffsetMode.Half means 0.5 is added anyways, so I would give this a try:
xNew = floor (*(x+0.5) * floatScaleNew / floatScaleOld)+0.5)
Caveat: one has to be careful with negative values, so when you run some tests, include both positive and negative values (unless negatives are irrelevant to your app). 2. As a big alternative you could simply use the function they use without having direct access to it; this is how it works: make a synthetic image, width=your original width, height=1; fill it with a wedge, i.e. the values 0, 1, 2, 3... etc. if it is a gray image; or perhalps (0,0,0), (1,1,1), (2,2,2), (3,3,3) if you prefer a regular RGB image (you may need a modulo-256 then). now let the system apply your scaling to it (in x direction), yielding a larger image with the same width as your actual scaled image. When you click the actual scaled image, use the mouse position and look into the scaled synthetic image; it will return a pixel value which equals the original x coordinate (or at least the lowest 8-bits of it if your synthetic is RGB). You can use the same trick in the other direction of course (i.e. there is no need to have a 2-D synthetic image). :)
Luc Pattyn [My Articles] Nil Volentibus Arduum
-
(this gibberish sentence has been necessary to get the message accepted by CP as it "appears to have already been posted") No I've never seen that function being available. However there are two simple solutions for what you seem to want: 1. the interpolation is quite simple, it basically is a linear re-scaling, something like:
xNew = x * scaleNew / scaleOld
and then the options determine the petty details. For one you need a floating point operation, and the result needs turned into an int again; that is where NearestNeighbor comes in (it basically means regular rounding: less than 0.5 becomes 0; 0.5 or more becomes 1). And PixelOffsetMode.Half means 0.5 is added anyways, so I would give this a try:
xNew = floor (*(x+0.5) * floatScaleNew / floatScaleOld)+0.5)
Caveat: one has to be careful with negative values, so when you run some tests, include both positive and negative values (unless negatives are irrelevant to your app). 2. As a big alternative you could simply use the function they use without having direct access to it; this is how it works: make a synthetic image, width=your original width, height=1; fill it with a wedge, i.e. the values 0, 1, 2, 3... etc. if it is a gray image; or perhalps (0,0,0), (1,1,1), (2,2,2), (3,3,3) if you prefer a regular RGB image (you may need a modulo-256 then). now let the system apply your scaling to it (in x direction), yielding a larger image with the same width as your actual scaled image. When you click the actual scaled image, use the mouse position and look into the scaled synthetic image; it will return a pixel value which equals the original x coordinate (or at least the lowest 8-bits of it if your synthetic is RGB). You can use the same trick in the other direction of course (i.e. there is no need to have a 2-D synthetic image). :)
Luc Pattyn [My Articles] Nil Volentibus Arduum
Thank you for your answer. At the moment, I use a formula similar to your first aproach where I get an error of up to +/- 1 pixel - it may be enough for the moment... Your second aproach is clever. Perhaps I will try it later (using an invisible bitmap filled with the index as rgba value ...). Alex