Display Jpegs from USB - image position offsets?

Hello --

I am following this recent post on how to display images on the Giga display...

Am having some trouble trying to figure out how to place an image at a specific coordinate pair and apply scaling of image with jpeg.decode() function. Using the second batch of code found there, all works fine out of the box.

I then tried something like this...

void loop() {
int x, y;
display.setRotation(1);
jpeg.decode(200, 200, JPEG_SCALE_HALF);
drawJpeg("image.jpg", 0, 0);
delay(4000);
...}

...attempting to have the image drawn 200px into the screen at half scale (of a 800x480px image).

From the start, just writing...

drawJpeg("image.jpg", 200, 200);

...wouldn't do the trick, neglecting the scaling option.

In the example provided at the above post, in the JpegFunc.ino tab, below in void processJPGFile() there are some lines to edit which makes a blanket application of the position and scaling, and it works, but that's not particularly what I want.

//  jpeg.decode(0, 0, decode_options);  //  default setting from example
jpeg.decode(200, 200, JPEG_SCALE_HALF);

If someone might suggest a method to draw images to the display at specific locations on a per image basis, I will be very appreciative. Using jpeg.decode() seems like the way to go, I just lack experience to get there.

The code on the link is not fully correct. See the source of method

It doesn't use a coordinate (200,200) and invariably draw the image at point 0,0.

I think that the author of that topic is a novice himself and the thread is not a good source of the code for you.

This is only a recent foray into TFT displays for me, with this Giga Display. Drawing the image at a particular x & y (e.g. 200, 200) seems familiar according the Adafruit_GFX library, at least from the tutorials with BMPs.
But the jpeg.decode() does work in positioning and scaling, just not as I would like in treating individual image objects. Seemed to be the only thing that works at this point for drawing an image elsewhere than at the origin 0,0.

It can, although maybe not as direct. I have played around with different variations of picture viewers, that I use mostly to test out different boards and displays...
That supports BMP, JPEG, PNG. The last two are through the libries JPEGDEC, PNGdec.

I have played around with a couple variations of it on the GIGA with the GIGA display.
Which most of the code is up in my github project: KurtE/Arduino_GIGA-stuff: This is my GIGA test sketches and other like stuff for Arduino GIGA boards

LIke, the one tft_picture_view_sd_giga_shield_24Bit.
The main parts of the JPEG support in the section like:

#ifdef __JPEGDEC__
JPEGDEC jpeg;


void processJPGFile(WrapperFile &jpgFile, const char *name, bool fErase) {
    int image_size = jpgFile.size();
    jpgFile.seek(0);
    Serial.println();
    Serial.print((uint32_t)&jpgFile, HEX);
    Serial.print(F(" Loading JPG image '"));
    Serial.print(name);
    Serial.print("' ");
    Serial.println(image_size, DEC);
    uint8_t scale = 1;
    if (jpeg.open((void *)&jpgFile, image_size, nullptr, myReadJPG, mySeekJPG, JPEGDraw)) {
        int image_width = jpeg.getWidth();
        int image_height = jpeg.getHeight();
        int decode_options = 0;
        Serial.print("Image size: ");
        Serial.print(image_width);
        Serial.print("x");
        Serial.print(image_height);

        // Try setting to 24 bit mode
        jpeg.setPixelType(RGB8888);

        switch (g_JPGScale) {
            case 1:
                scale = 1;
                decode_options = 0;
                break;
            case 2:
                scale = 2;
                decode_options = JPEG_SCALE_HALF;
                break;
            case 4:
                scale = 4;
                decode_options = JPEG_SCALE_QUARTER;
                break;
            case 8:
                scale = 8;
                decode_options = JPEG_SCALE_EIGHTH;
                break;
            default:
                {
                    if ((image_width > g_jpg_scale_x_above[SCL_16TH]) || (image_height > g_jpg_scale_y_above[SCL_16TH])) {
                        decode_options = JPEG_SCALE_EIGHTH | JPEG_SCALE_HALF;
                        scale = 16;
                    } else if ((image_width > g_jpg_scale_x_above[SCL_EIGHTH]) || (image_height > g_jpg_scale_y_above[SCL_EIGHTH])) {
                        decode_options = JPEG_SCALE_EIGHTH;
                        scale = 8;
                    } else if ((image_width > g_jpg_scale_x_above[SCL_QUARTER]) || (image_height > g_jpg_scale_y_above[SCL_QUARTER])) {
                        decode_options = JPEG_SCALE_QUARTER;
                        scale = 4;
                    } else if ((image_width > g_jpg_scale_x_above[SCL_HALF]) || (image_height > g_jpg_scale_y_above[SCL_HALF])) {
                        decode_options = JPEG_SCALE_HALF;
                        scale = 2;
                    }
                }
        }
        Display.beginDraw();
        if (fErase && ((image_width / scale < g_tft_width) || (image_height / scale < g_tft_height))) {
            fillScreen((uint16_t)g_background_color, false);
        }

        if (g_center_image) {
            g_image_offset_x = (g_tft_width - image_width / scale) / 2;
            g_image_offset_y = (g_tft_height - image_height / scale) / 2;
        } else {
            g_image_offset_x = 0;
            g_image_offset_y = 0;
        }
        g_image_scale = scale;
        Serial.print("Scale: 1/");
        Serial.print(g_image_scale);
        Serial.print(" Image Offsets (");
        Serial.print(g_image_offset_x);
        Serial.print(", ");
        Serial.print(g_image_offset_y), Serial.println(")");

        jpeg.decode(0, 0, decode_options);
        jpeg.close();
        //Display.endDraw();
    } else {
        Serial.println("Was not a valid jpeg file");
    }
    jpgFile.close();
}


int32_t myReadJPG(JPEGFILE *pjpegfile, uint8_t *buffer, int32_t length) {
    if (!pjpegfile || !pjpegfile->fHandle) return 0;
    return ((WrapperFile *)(pjpegfile->fHandle))->read(buffer, length);
}
int32_t mySeekJPG(JPEGFILE *pjpegfile, int32_t position) {
    if (!pjpegfile || !pjpegfile->fHandle) return 0;
    return ((WrapperFile *)(pjpegfile->fHandle))->seek(position);
}

int JPEGDraw(JPEGDRAW *pDraw) {
    if (g_debug_output) {
        Serial.print("jpeg draw: x,y=");
        Serial.print(pDraw->x);
        Serial.print(",");
        Serial.print(pDraw->y);
        Serial.print(", cx,cy = ");
        Serial.print(pDraw->iWidth);
        Serial.print(",");
        Serial.println(pDraw->iHeight);
    }
    writeClippedRect24(pDraw->x, pDraw->y, pDraw->iWidth, pDraw->iHeight, (uint32_t *)pDraw->pPixels);
    return 1;
}
#endif

Note: my sketch has the ability read in a quick and dirty options file, that allows me to hard code scale, or to give hints... But the main things are:

After calling jpeg.open, you can the call the jpeg.getwidth() and jpeg.gitHeight(), and
use those values to decide if you wish to scale and/or offset the image.

I don't use the library to do the offset. Instead when the library does a callback for us to draw something, in my case JPEGDraw method, this method calls another
of my internal functions writeClippedRect24, which adds on the offsets, and
then puts the pixels out to the display.

Hope that makes sense.

Gaining a new familiarity with this, I get some sense of what you are saying.

What I have in mind is something like printing text on the display...set the cursor, print here. That is why I thought jpeg.decode() would be the ticket.

The function drawjpeg with arguments x and y I think I am wrong in understanding how to use that, as it does not do what wrongly assume it should. See above.