第一次嘗試旋轉和縮放位圖時,我做了一個顯而易見的選擇:從源矩陣中取出每個像素,通過旋轉和縮放對其進行變換,然後將值寫入目標中變換後的位置。結果如下所示:
bitmap = J( bmy = 200, bmx = 300, RGB Color( 1, 1, 1 ) );//white
scale = 3;
tranmat = (1 || 0 || 80) |/ (0 || 1 || 10) |/ (0 || 0 || 1); // 2D translation matrix
scalmat = (scale || 0 || 0) |/ (0 || scale || 0) |/ (0 || 0 || 1); // 2D scale matrix
angle = 33 * Pi() / 180;
sangle = Sin( angle );
cangle = Cos( angle );
rotamat = (cangle || -sangle || 0) |/ (sangle || cangle || 0) |/ (0 || 0 || 1); // 2D rotation matrix
forward = (tranmat * scalmat * rotamat)`; // transpose here
// make a sample image
testimage = Text Box( "matrix", <<SETWRAP></SETWRAP>
Transformed text has holes轉換後的文本有漏洞
看起來很糟糕。 正確的方法是使用變換矩陣的逆並詢問“對於目標位圖中的每個像素,我應該使用源中的哪個像素?” 但答案幾乎總是落在四個像素之間。 一個合理的答案是使用四個像素的加權平均值,更複雜的答案可能看起來像雙三次插值。 此代碼使用加權平均值:
// this bitmap is used to build the image. drawtext will write
// each string into this bitmap.
bitmap = J( bmy = 300, bmx = 580, RGB Color( 1, 1, 1 ) );//white
// drawtext is a slow routine that draws a text string into a buffer,
// then samples that buffer to create a rotated, scaled copy in the
// bitmap buffer.
drawtext = Function(
{x = 0, y = 0, txt = "hello", degAngle = 0, xjust = 0, yjust = 1, fontsize = 99, scale = .5, textcolor = RGB Color( 0, 0, 0 )}, // parms
{// locals, initialized. Creates a transform matrix and its inverse
t = Text Box( txt, <<SETWRAP></SETWRAP>
Sampling the source image with linear interpolation使用線性插值對源圖像進行採樣
代碼的後半部分與其說是關於矩陣變換,不如說是製作一幅有趣的圖畫。 水平條紋是通過將多個圖像副本混合在一起創建的,每個副本移動一個像素,並保留較少的更遠的移動。
Big, tilted, orange大,傾斜,橙色