image as byte array

Is there any way to convert any regular image into an array, or access an image’s raw data as if it were an array? i’m writing a function to stretch an image by any amount on the x and/or y axis, and on the x axis it works fine but if i attempt to scale on the y axis it becomes unbearably laggy on real hardware (Kitronik Arcade). I’m not fully sure if this is a hardware issue or if the code i wrote is just slow, but since there was no function to copy or even just get any of the rows in an image (getRows and setRows won’t work because they are actually getting columns, and they work fine when implemented for horizontal stretching) i had to instead copy pixel by pixel since i couldn’t find any other way to do it;

if (y != 1) for (let i = 0; i<tempImg2.height; i++) {
    for (let j = 0; j < tempImg2.width; j++)
        tempImg2.setPixel(j, i, tempImg.getPixel(j, i * 1 / y));
} else tempImg2 = tempImg;

This function seemed to work fine until i tried to use it on real hardware, where if i didn’t add any pause in the main loop it would lag out completely and just freeze when the scaling got too much. If i add a one millisecond pause in the loop, the framerate goes down to just 2 frames per second at it’s worst, which is way too low to be any kind of practical at all.

I am honestly a little bit stumped about what to do at this point, and i would love some help from someone who might know a little better about how this can be solved, or who can maybe assist me with some optimization.

For additional context, this is the entire script:

function stretch(img: Image, x: number = 1, y: number = 1): Image {
    if (x < 0) { x = -x; img.flipX(); }
    if (y < 0) { y = -y; img.flipY(); }

    let tempImg = image.create(img.width * x + 1, img.height);
    let buf = Buffer.create(tempImg.height);

    if (x != 1) for (let i = 0; i<tempImg.width; i++) {
        img.getRows(i * 1/x, buf);
        tempImg.setRows(i, buf);
    } else tempImg = img;

    let tempImg2 = image.create(tempImg.width, tempImg.height * y + 1);

    if (y != 1) for (let i = 0; i<tempImg2.height; i++) {
        for (let j = 0; j < tempImg2.width; j++)
            tempImg2.setPixel(j, i, tempImg.getPixel(j, i * 1 / y));
    } else tempImg2 = tempImg;

    return tempImg2;
}

let a: number, b: number = 0;

let stretchedImage: Image;
let mySprite = sprites.create(assets.image`myImage`, SpriteKind.Player);

let start = game.runtime();

forever(function () {
    pause(1);
    a = Math.sin(start / 1000) * 2;
    b = Math.sin(start / 1100)// * 5.22;

    stretchedImage = stretch(assets.image`myImage`, a, b);

    mySprite.setImage(stretchedImage);
    mySprite.x = 80; // Half of screen width
    mySprite.y = 60; // Half of screen height

    scene.backgroundImage().fill(15);
    scene.backgroundImage().print(
        Math.round(1000 / (game.runtime() - start)).toString(), 0, 0, 9
    );

    start = game.runtime();
})

While we wait to see if anyone has a direct answer to your question, I need to check, have you tried the scaling extension, yet?

“sprite-scaling”: “*”

You could probably, at least, look at the code for the extension to see how MakeCode goes about things: