SD card slideshow Pico W images shift to the left

Hello,

I realize it’s a long shot,but maybe someone has an idea. Pico W with a Display Pack 2 and an images stored on a micro sd ( adapter connected to SP0).

The issue is that the images load a bit offset to the left and with each change they move further to the left. Images have the proper size and resolution. Loaded Pimoroni flavored micro python,latest version but also tried with previous versions. Same behavior.

I am running out of ideas and any help would be appreciated.

Here is my code :

import picodisplay

from picodisplay import Picodisplay, DISPLAY_PICO_DISPLAY_2 as display

import picographicsfrom machine import Pin, SPIimport jpegdecimport sdcardimport osimport randomimport timefrom pimoroni import Buttonfrom pimoroni import RGBLEDimport gcimport uos

set up the display . These are copied from default Image Pack2 examples

#display = picodisplay.Picodisplay(display=picodisplay.DISPLAY_PICO_DISPLAY_2, rotate=0)display = picographics.PicoGraphics(display=picographics.DISPLAY_PICO_DISPLAY_2, rotate=0)display.set_backlight(1.0)

Set up the display

display = Picodisplay(DISPLAY)

#display = (display)

WIDTH, HEIGHT = display.get_bounds()

#WIDTH = 320#HEIGHT = 240

Setup buttons

button_a = Button(12)button_b = Button(13)button_x = Button(14)button_y = Button(15)

led = RGBLED(6, 7, 8) # Physical hardware pins connections for RGB LED

From CPython Lib/colorsys.py . Set this for Rainbow LED

def hsv_to_rgb(h, s, v):if s == 0.0:return v, v, vi = int(h * 6.0)f = (h * 6.0) - ip = v * (1.0 - s)q = v * (1.0 - s * f)t = v * (1.0 - s * (1.0 - f))i = i % 6if i == 0:return v, t, pif i == 1:return q, v, pif i == 2:return p, v, tif i == 3:return p, q, vif i == 4:return t, p, vif i == 5:return v, p, qh = 0

Set up the SD card

sd_spi = SPI(0, sck=Pin(18, Pin.OUT), mosi=Pin(19, Pin.OUT), miso=Pin(16, Pin.OUT))sd = sdcard.SDCard(sd_spi, Pin(22))os.mount(sd, “/sd”)

Create a new JPEG decoder

j = jpegdec.JPEG(display)

Time between slides (in seconds)

IMAGE_PAUSE = 0.50 * 60  # 5 minutes between slides

def clear_screen():“”“Clear the screen with black”“”display.set_pen(display.create_pen(0, 0, 0))display.clear()display.update()

def display_image(filename):“”“Display a JPEG image on the screen”“”try:clear_screen()  # Clear screen before displaying new imagej.open_file(filename)j.decode(0, 0, jpegdec.JPEG_SCALE_FULL)display.update()print(f"Displayed: {filename}“)except Exception as e:print(f"Error displaying {filename}: {e}”)# Display error messagedisplay.set_pen(display.create_pen(255, 0, 0))display.text(f"Error loading image", 10, 10, 240, 2)display.update()

Get list of JPEG files on SD card.older micropython versions. endswith not supported

files = [f for f in os.listdir(“/sd”) if f.lower().endswith((“.jpg”, “.jpeg”))]

Display intro image (assuming “intro.jpg” exists on SD card)

intro_image = “/sd/intro.jpg”try:display_image(intro_image)except:# If no intro image, display first imagedisplay_image(“/sd/” + files[0])

Wait for any button press to start slideshow

print(“Waiting for button press to start slideshow…”)while True:if button_a.is_pressed or button_b.is_pressed or button_x.is_pressed or button_y.is_pressed:breaktime.sleep(0.1)

Initialize slideshow variables

current_index = random.randrange(len(files))last_change_time = time.time()last_button_press = time.time()
Main slideshow loop

while True:

h += 1 # this is needed for Rainbow LED
r, g, b = [int(255 * c) for c in hsv_to_rgb(h / 360.0, 1.0, 1.0)]  # rainbow magic
led.set_rgb(r, g, b)      # Set LED to a converted HSV value

now = time.time()

# Check for button presses with debounce
if (button_a.is_pressed or button_b.is_pressed) and (now - last_button_press > 0.5):
    button_b_led = led.set_rgb(0, 255, 0)
    last_button_press = now
    
    if button_a.is_pressed:  # Previous image
        current_index = (current_index - 1) % len(files)
        print("Button A pressed - previous image")
        display.update() 

        
    elif button_b.is_pressed:  # Next image
        current_index = (current_index + 1) % len(files)
        button_x_led = led.set_rgb(0, 0, 255)
        print("Button B pressed - next image")

        
    # Display the selected image
    display_image("/sd/" + files[current_index])
    last_change_time = now

    
# Automatic slideshow advance
elif now - last_change_time >= IMAGE_PAUSE:
    current_index = (current_index + 1) % len(files)
    display_image("/sd/" + files[current_index])
    last_change_time = now
    
time.sleep(0.1)  # Small delay to reduce CPU usage

Thank you.

I think something has gone badly wrong with the code you copied, because it’s horribly corrupted and barely readable.

That said, nothing super obvious leaps out - I’d double check that all the images you have on your SD card are the right size; my initial guess is that there are other images with slightly different dimensions (from when you were resizing them maybe?) that are clouding the issue.

Thank you for taking the time to respond. I will check again,but I’ve sized them for the display pack 2 and checked them.

Having said that,even if the were the wrong size,why would they move/shift their position at each refresh? I don’t understand that one.

Well, because (from what I can make out of the strangely formatted code) it cycles through the images it finds on the card - if you have a bunch of different crops/dimensions of the same image, it will appear to be ‘shifting’ when it’s actually opening a different file.

I mean that’s all guesswork, because I can’t see your SD card ;)

No,all of them are sized properly to avoid using the joeg decoder to do the resizing. It starts a bit shifted to the left and with each iteration moves further to the left. I think i’ll give up and do it on a esp 😁

If it were me, I’d probably add something in display_image() to dump the jpeg size to the console, just to reassure myself that it was reading them as expected.

You could also try switching to pngs, in case the jpg library is playing up, but it’s hard to imagine what it could be doing (unless the jpgs are progressive or some other odd format?)

Thanks,I’ll try to play more. Jpegs are not progressive. Funny thing is I have other scripts I’ve built and they work with the same images. I was simply trying to get this one to display images on a predetermined loop and go next/previous with the buttons.