第一次嘗試旋轉和縮放位圖時,我做了一個顯而易見的選擇:從來源矩陣中取出每個像素,透過旋轉和縮放對其進行轉換,然後將值寫入目標中的轉換位置。結果如下:
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 holesTransformed text has holesTransformed text has holesTransformed 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 interpolationSampling the source image with linear interpolationSampling the source image with linear interpolationSampling the source image with linear interpolation使用線性內插法對來源影像進行取樣
程式碼的後半部與其說是關於矩陣變換,不如說是製作了一幅有趣的圖片。 水平條紋是透過將影像的多個副本混合在一起創建的,每個副本移動一個像素,並保留較少的較遠的移動。
Big, tilted, orangeBig, tilted, orangeBig, tilted, orangeBig, tilted, orange大,傾斜,橙色