<p>I am wondering about techniques for rendering a rotated and or scaled raster image. Currently I use the following algorithm</p>
<ol>
<li>Render everything at double resolution and store the result in <code>A</code></li>
<li>For each pixel in output image, assign it the value of the average of the four pixels in <code>A</code></li>
</ol>
<pre class="lang-cpp prettyprint-override"><code>img(col, row) = 0.25f * (tmp(2 * col, 2 * row) + tmp(2 * col + 1, 2 * row) + tmp(2 * col, 2 * row + 1) + tmp(2 * col + 1, 2 * row + 1));
</code></pre>
<p>Current sampler looks like this:</p>
<pre class="lang-cpp prettyprint-override"><code>            auto const loc_ret = vec2_t{static_cast&lt;double&gt;(col), static_cast&lt;double&gt;(row)};
            auto const src_pos =
                scale_factor * transform(loc_ret - loc_src_ret_coord, rot_x, rot_y) + origin_src;
            if(src_pos[0] &gt;= 0 &amp;&amp; src_pos[0] &lt; src.width() &amp;&amp; src_pos[1] &gt;= 0
               &amp;&amp; src_pos[1] &lt; src.height())
            {
                auto const src_pixel =
                    src(static_cast&lt;uint32_t&gt;(src_pos[0]), static_cast&lt;uint32_t&gt;(src_pos[1]));
                auto&amp; ret_pixel =
                    ret((col + ret.width()) % ret.width(), (row + ret.height()) % ret.height());
                ret_pixel = blend(ret_pixel, src_pixel, opacity);
            }
</code></pre>
<p>where</p>
<pre class="lang-cpp prettyprint-override"><code>auto const scale_factor = 1.0 / (scale * layer.scaleFactor());
</code></pre>
<p>and scale is the scale used to down-sample the image once completed.</p>
<p>The algorithm works for rotated and down-scaled sources, however, it has no effect when the source is upscaled.</p>

CC BY-SA 4.0
2020-11-08T10:03:52.477Z
You just need better interpolation. Try bilinear, biquadratic, bicubic.
lightxbulb
CC BY-SA 4.0
2020-11-08T15:18:07.853Z
@lightxbulb I guess interpolation only applies when upscaling.
user877329
CC BY-SA 4.0
2020-11-08T16:22:18.747Z
It applies always when you're sampling the signal at locations where the data was not defined. Even when you're downscaling it.It's just that you additionally apply some convolution filter on top when downscaling.
lightxbulb
<image-processing><raster-image><supersampling>
How to render a rotated raster image with lesser aliasing
user877329
# How to render a rotated raster image with lesser aliasing

(Asked by: username_0 on 2020-11-08)

I am wondering about techniques for rendering a rotated and or scaled raster image. Currently I use the following algorithm

1. Render everything at double resolution and store the result in `A`
2. For each pixel in output image, assign it the value of the average of the four pixels in `A`

```cpp
img(col, row) = 0.25f * (tmp(2 * col, 2 * row) + tmp(2 * col + 1, 2 * row) + tmp(2 * col, 2 * row + 1) + tmp(2 * col + 1, 2 * row + 1));

```

Current sampler looks like this:

```cpp
            auto const loc_ret = vec2_t{static_cast<double>(col), static_cast<double>(row)};
            auto const src_pos =
                scale_factor * transform(loc_ret - loc_src_ret_coord, rot_x, rot_y) + origin_src;
            if(src_pos[0] >= 0 && src_pos[0] < src.width() && src_pos[1] >= 0
               && src_pos[1] < src.height())
            {
                auto const src_pixel =
                    src(static_cast<uint32_t>(src_pos[0]), static_cast<uint32_t>(src_pos[1]));
                auto& ret_pixel =
                    ret((col + ret.width()) % ret.width(), (row + ret.height()) % ret.height());
                ret_pixel = blend(ret_pixel, src_pixel, opacity);
            }

```

where

```cpp
auto const scale_factor = 1.0 / (scale * layer.scaleFactor());

```

and scale is the scale used to down-sample the image once completed.

The algorithm works for rotated and down-scaled sources, however, it has no effect when the source is upscaled.

**Tags:** image-processing, raster-image, supersampling

> **Comments:**
> **username_1**: You just need better interpolation. Try bilinear, biquadratic, bicubic.  
> **username_0**: @username_1 I guess interpolation only applies when upscaling.  
> **username_1**: It applies always when you're sampling the signal at locations where the data was not defined. Even when you're downscaling it.It's just that you additionally apply some convolution filter on top when downscaling.  

---

## 0 answers

