Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to mirror second screen only #1731

Closed
C00kieGamez opened this issue Nov 12, 2024 · 4 comments
Closed

Unable to mirror second screen only #1731

C00kieGamez opened this issue Nov 12, 2024 · 4 comments

Comments

@C00kieGamez
Copy link

C00kieGamez commented Nov 12, 2024

Hello, I'm looking to have the same image displayed on both connected displays but have the second display mirrored horizontally without affecting the first display at all.

I have tried using pixel_mapper_configs such as ";Mirror:H" and such with chain_length = 1 and chain_length = 2 along with other configurations of RGBMatrixOptions()

This is my configuration so far

# LED matrix configuration
options = RGBMatrixOptions()
options.rows = 32
options.cols = 64
options.hardware_mapping = 'adafruit-hat'
options.gpio_slowdown = 4
options.chain_length = 1
options.parallel = 1
options.brightness = 100
options.pixel_mapper_config = ";Mirror:H"
#options.show_refresh_rate = 1

# Initialize the LED matrix
matrix = RGBMatrix(options=options)
canvas = matrix.CreateFrameCanvas()


...

canvas = matrix.SwapOnVSync(canvas)

The displaying works great on one display and good on the other connected other then wanting the second display to be mirrored with the first display just how it is, any idea on how to do that? I cant find anything of that sorts inside the documentation.

Any help is greatly appreciated!

@marcmerlin
Copy link
Collaborator

from reading the documentation, mirror does not work on just one display, it's a global setting that works on everything.
So it's all or nothing, sorry.
Of course, you could start writing your own code to do something custom but it would not be a flag.
This code will not do what you want, but will show you how to do custom remapping of pixel location:
#1014
after that, you're on your own, good luck :)

@C00kieGamez
Copy link
Author

what I thought, alright sounds good! Pretty sure I came up with a solution that will require a little bit more code but should be fine, thanks!

@davemaster
Copy link

what I thought, alright sounds good! Pretty sure I came up with a solution that will require a little bit more code but should be fine, thanks!

Great, share your solution here please.. include some pictures/videos. Thanks in advance.

@C00kieGamez
Copy link
Author

C00kieGamez commented Nov 16, 2024

It is a very hack solution but basically, you just need to save what points you adding to the canvas that frame, since the canvas cannot be directly accessed for getting pixels (only setting them) you need a separate variable (if there is another easier way of getting the canvas pixels please let me know). And then you simply mirror them.

#create a canvas

options = RGBMatrixOptions()
options.rows = 32
options.cols = 64
options.hardware_mapping = 'adafruit-hat'
options.gpio_slowdown = 4


#using a chain length of two

options.chain_length = 2

options.parallel = 1
options.brightness = 100

matrix = RGBMatrix(options=options)

canvas = matrix.CreateFrameCanvas()

#getting the canvas width and height
canvas_width = canvas.width
canvas_height = canvas.height

#variable for storing the pixel_data on the canvas for that frame
pixel_data = [[(0, 0, 0) for _ in range(canvas_height)] for _ in range(canvas_width)]

#function for clearing the data (reset it back to empty)
def clearPixelData():
    global pixel_data
    pixel_data = [[(0, 0, 0) for _ in range(canvas_height)] for _ in range(canvas_width)]


#function to store a pixel at that position
def storePixelData(x, y, r, g, b):
    global pixel_data
    if 0 <= x < canvas_width and 0 <= y < canvas_height:
        pixel_data[x][y] = (r, g, b)




#at any point you want to set a pixel on the canvas you also call storePixelData to save it
canvas.SetPixel(x, y, *color)
storePixelData(x,y, *color)


while True:
    #resetting the canvas and the holder variable
    clearPixelData()
    canvas.Clear()

    #the actual copying and mirroring part, assuming that inside your code you only draw to the first part of the canvas
    #(to width 64) and none farther, get all the pixels from top to bottom left to right until you reach the middle point on 
    # the width (position 64)
    for x in range(canvas_width//2): #only go half of the total canvas
                for y in range(canvas_height): #go the entire canvas height
                
                    #Get the pixel at the position plus 64 (one whole screen wide)
                    r, g, b = pixel_data[x + 64][y]
                    #Set that pixel onto the other side of the canvas
                    canvas.SetPixel(canvas_width - x - 65, y, r, g, b)
                    
                    
    #draw onto the matrix                
    canvas = matrix.SwapOnVSync(canvas)

The main issue with this is needing to know what pixels you are writing to the canvas, in situations such as putting an image onto the canvas such as using canvas.SetImage(image.convert("RGB")). You don't know what pixels are being set so you must loop over the image in some other way and gather the pixel data yourself. This could be solved and would also save making a new variable and the memory required with using this variable if you could access the pixel values from the canvas using GetPixel() or something. I really hope I'm missing a way you can do that because that would clean this up and simplify this so much. Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants