La primera vez que intenté rotar y escalar un mapa de bits, tomé la decisión obvia: tomar cada píxel de la matriz de origen, transformarlo con rotación y escala, y escribir el valor en la ubicación transformada en el destino.El resultado se ve así:
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 holesEl texto transformado tiene agujeros
Parece terrible. La forma correcta es usar el inverso de la matriz de transformación y preguntar "Para cada píxel en el mapa de bits de destino, ¿qué píxel debo usar de la fuente?" Pero la respuesta casi siempre estará entre cuatro píxeles. Una respuesta razonable es usar un promedio ponderado de los cuatro píxeles, y las respuestas más complicadas podrían parecer una interpolación bicúbica. Este código utiliza un promedio ponderado:
// 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 interpolationMuestreo de la imagen de origen con interpolación lineal
La última mitad del código no se trata tanto de transformaciones de matriz como de hacer una imagen interesante. El rayado horizontal se crea combinando varias copias de la imagen, cada una desplazada un píxel, y manteniendo menos de los desplazamientos más distantes.
Big, tilted, orangeGrande, inclinado, naranja