La première fois que j'ai essayé de faire pivoter et de mettre à l'échelle un bitmap, j'ai fait le choix évident : prendre chaque pixel de la matrice source, le transformer avec une rotation et une mise à l'échelle, et écrire la valeur à l'emplacement transformé dans la destination.Le résultat ressemble à ceci :
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 holesLe texte transformé a des trous
Ça a l'air terrible. La bonne méthode consiste à utiliser l'inverse de la matrice de transformation et à demander "Pour chaque pixel du bitmap de destination, quel pixel dois-je utiliser à partir de la source ?" Mais la réponse se situera presque toujours entre quatre pixels. Une réponse raisonnable consiste à utiliser une moyenne pondérée des quatre pixels, et des réponses plus compliquées pourraient ressembler à une interpolation bi-cubique. Ce code utilise une moyenne pondérée :
// 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Échantillonnage de l'image source avec interpolation linéaire
La dernière moitié du code ne concerne pas tant les transformations matricielles que la création d'une image intéressante. La strie horizontale est créée en mélangeant un certain nombre de copies de l'image ensemble, chacune décalée d'un pixel, et en gardant moins les décalages les plus éloignés.
Big, tilted, orangeGrand, incliné, orange