virtualabs / pixoo-client

Divoom Pixoo Client for Python3
63 stars 13 forks source link

Corrupt Pixels #3

Closed lordtaco closed 2 years ago

lordtaco commented 2 years ago

Hi, I bought a Pixoo Max with the intention of scripting a way to send custom images to the display. Everything works, except for this weird bug that I can't solve. When I connect to it using the PixooMax routine, it seems to garble a random amount of pixels at the bottom.

See photo for what I am talking about: https://lordtaco.com/pixoo/picture1.jpg

If I use the normal Pixoo routine, it works perfectly, although in 16x16 instead of 32x32, like so: https://lordtaco.com/pixoo/picture2.jpg

I've messed around with different image formats and settings, but I can't find a fix at all. Any insights as to why this is happening? Thanks!

feliperafael commented 2 years ago

I have the same problem

virtualabs commented 2 years ago

Looks like a bad picture encoding, but that's weird. I will check this today and see if I can reproduce, stay tuned.

virtualabs commented 2 years ago

Cannot reproduce with some of my 32x32 images, could you send me your source image ?

HoroTW commented 2 years ago

Hey there, I'm able to reproduce the issue on my Pixoo Max using this Image

It looks like this

cheers :)

EDIT: I tried another image and it seems that the first pixel that gets coruppted is x19 y25 - these are the data of the pixels: x19 y25 r251 g221 b203 | #FBDDCB x19 y25 r191 g57 b70 | #BF3946

Just to give as much info as I can: I crop the images using photopea (online image editor). I use a rpi to connect to the pixoo.

virtualabs commented 2 years ago

Thanks for the image, it helped a lot to reproduce the bug. In fact, it seems to be a palette issue, the bottom pixels are referencing the wrong RGB data in the palette so it is all messy. I need to do more testing (and maybe reverse-engineering as well) to figure out what's happening here.

lordtaco commented 2 years ago

Here is an example source image: https://lordtaco.com/pixoo/clipper.png

And when sent to the Pixoo, it looks like this: https://lordtaco.com/pixoo/picture3.jpg

I've tried all sorts of different images, resizing them down to 32x32 first, different image formats, color depths, etc. and I get pretty much the same results each time.

I also tried with HoroTW's source image and got the same thing: https://lordtaco.com/pixoo/picture4.jpg

I'm using a Windows 10 desktop to run the script. Please let me know if I can provide any more info. Thank you!

feliperafael commented 2 years ago

follow an image that also generated an error for me:

https://github.com/feliperafael/pixoo-img

HoroTW commented 2 years ago

Hey I found the root of the issue, will comment back in a few minutes.

cheers ^^

lordtaco commented 2 years ago

Hey,

I looked at your PR and applied your change to my code and I can confirm it works! I have tested with a bunch of different images and they are all perfect.

Amazing stuff, thank you so much @HoroTW.

HoroTW commented 2 years ago

Good :) - any reason why you not just accepted the pull request?

lordtaco commented 2 years ago

I am not the author, so I don't think I can do that. But I can confirm your fix works for me.

virtualabs commented 2 years ago

I've found the same this afternoon, but had no time to provide a fix. This bug is caused by an over sized packet sent to the Pixoo Max. If I take the girl picture as an example, it contains 992 different colors so each pixel is stored on 10 bits (instead of 8). In my pixel encoding routine, each pixel color index is turned into a series of bits which are then aggregated into bytes, based on a bit width derived from the actual palette size. The problem is that in this encoding loop, the aggregated bits grow faster than the conversion into bytes, resulting in an incomplete encoded data ! This routine returned an encoded pixel array of 1024 values instead of 1280, which is pretty bad.

Moreover, the size of a frame sent over bluetooth must not exceed a specific number of bytes, but in this case we have to send way too much bytes because of the 10-bits encoding and the 992 different colors used.

Reducing the number of colors indeed reduces the number of bits used to encode a pixel color index, therefore reducing the overall frame size under the maximum length, and everything is OK. I think your fix may be improved and we can go over 256 colors, allowing better image resolution, while keeping the frame size under its maximum size.

HoroTW commented 2 years ago

@lordtaco sorry, you are right 😁

@virtualabs Yes, I think you are right - I tried to change that aswell but had no luck and then went for the quick fix because of time restrictions :)

virtualabs commented 2 years ago

Well, looks like it is the best fix as convert() only accepts a 256-color palette. I will merge your fix and push another fix for the bug I mentioned before.

virtualabs commented 2 years ago

PR #4 merged, and I made a few other modifications. All good now, it displays all the images nicely :smile: ! Thanks all for your help :+1: !