Skip to content

Commit 589ae66

Browse files
committed
Added 2D image effect
1 parent 5602fde commit 589ae66

File tree

3 files changed

+98
-30
lines changed

3 files changed

+98
-30
lines changed

platformio.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ build_flags =
139139
#For ADS1115 sensor uncomment following
140140
; -D USERMOD_ADS1115
141141
#For POV Display uncomment following
142-
-D USERMOD_POV_DISPLAY
142+
-D USERMOD_IMG_DISPLAY
143143

144144
build_unflags =
145145

usermods/pov_display/usermod_pov_display.h renamed to usermods/img_display/usermod_img_display.h

Lines changed: 88 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
#include "wled.h"
33
#include <PNGdec.h>
44
#include <AnimatedGIF.h>
5-
#define BRI 3
5+
#define BRIGHT_SHIFT 3
66
#define FX_MODE_POV_IMAGE 255
7+
#define FX_MODE_2D_IMAGE 255
78
static const char _data_FX_MODE_POV_IMAGE[] PROGMEM = "POV Image@!;;;1";
8-
9+
static const char _data_FX_MODE_2D_IMAGE[] PROGMEM = "2D Image@!;;;2";
910
AnimatedGIF gif;
1011
PNG png;
1112
File f;
@@ -65,7 +66,7 @@ int32_t seekPNG(PNGFILE *pFile, int32_t iPos)
6566
int32_t seekGIF(GIFFILE *pFile, int32_t iPos)
6667
{ return seekFile((IMGFILE*) pFile, iPos); }
6768

68-
void pngDraw(PNGDRAW *pDraw) {
69+
void pngPOV(PNGDRAW *pDraw) {
6970
uint16_t usPixels[SEGLEN];
7071
png.getLineAsRGB565(pDraw, usPixels, PNG_RGB565_LITTLE_ENDIAN, 0xffffffff);
7172
for(int x=0; x < SEGLEN; x++) {
@@ -75,72 +76,129 @@ void pngDraw(PNGDRAW *pDraw) {
7576
byte b = (color & 0x1F);
7677
SEGMENT.setPixelColor(x, RGBW32(r,g,b,0));
7778
}
78-
busses.show();
79+
strip.show();
80+
}
81+
82+
void png2D(PNGDRAW *pDraw) {
83+
uint16_t usPixels[pDraw->iWidth];
84+
for(int y=0; y < pDraw->iWidth; y++) {
85+
png.getLineAsRGB565(pDraw, usPixels, PNG_RGB565_LITTLE_ENDIAN, 0xffffffff);
86+
for(int x=0; x < SEGLEN; x++) {
87+
uint16_t color = usPixels[x];
88+
byte r = ((color >> 11) & 0x1F);
89+
byte g = ((color >> 5) & 0x3F);
90+
byte b = (color & 0x1F);
91+
SEGMENT.setPixelColorXY(x, y, RGBW32(r,g,b,0));
92+
}
93+
}
94+
strip.show();
7995
}
8096

81-
void gifDraw(GIFDRAW *pDraw) {
97+
void gifPOV(GIFDRAW *pDraw) {
8298
uint8_t r, g, b, *s, *p, *pPal = (uint8_t *)pDraw->pPalette;
8399
int x, y = pDraw->iY + pDraw->y;
84-
85100
s = pDraw->pPixels;
86101
if (pDraw->ucDisposalMethod == 2) {
87102
p = &pPal[pDraw->ucBackground * 3];
88103
r = p[0]; g = p[1]; b = p[2];
89104
for (x=0; x<pDraw->iWidth; x++)
90-
{
91-
if (s[x] == pDraw->ucTransparent) {
105+
if (s[x] == pDraw->ucTransparent)
92106
SEGMENT.setPixelColor(x, RGBW32(r, g, b, 0));
93-
}
94-
}
95107
pDraw->ucHasTransparency = 0;
96108
}
97109

110+
98111
if (pDraw->ucHasTransparency) {
99112
const uint8_t ucTransparent = pDraw->ucTransparent;
100-
for (x=0; x<pDraw->iWidth; x++) {
113+
for (x=0; x<pDraw->iWidth; x++)
101114
if (s[x] != ucTransparent) {
102115
p = &pPal[s[x] * 3];
103-
SEGMENT.setPixelColor(x, RGBW32(p[0]>>BRI, p[1]>>BRI, p[2]>>BRI, 0));
116+
SEGMENT.setPixelColor(x, RGBW32(p[0]>>BRIGHT_SHIFT, p[1]>>BRIGHT_SHIFT, p[2]>>BRIGHT_SHIFT, 0));
104117
}
105-
}
106118
}
107119

108-
else // no transparency, just copy them all
109-
{
110-
for (x=0; x<pDraw->iWidth; x++)
111-
{
120+
else
121+
for (x=0; x<pDraw->iWidth; x++) {
112122
p = &pPal[s[x] * 3];
113123
SEGMENT.setPixelColor(x, RGBW32(p[0], p[1], p[2], 0));
114124
}
125+
strip.show();
126+
}
127+
128+
void gif2D(GIFDRAW *pDraw) {
129+
uint8_t r, g, b, *s, *p, *pPal = (uint8_t *)pDraw->pPalette;
130+
int x, y = pDraw->iY + pDraw->y;
131+
132+
s = pDraw->pPixels;
133+
if (pDraw->ucDisposalMethod == 2) {
134+
p = &pPal[pDraw->ucBackground * 3];
135+
r = p[0] >> BRIGHT_SHIFT; g = p[1] >> BRIGHT_SHIFT; b = p[2] >> BRIGHT_SHIFT;
136+
for (x=0; x<pDraw->iWidth; x++)
137+
if (s[x] == pDraw->ucTransparent)
138+
SEGMENT.setPixelColorXY(x, y, RGBW32(r,g,b,0));
139+
pDraw->ucHasTransparency = 0;
140+
}
141+
142+
if (pDraw->ucHasTransparency) {
143+
const uint8_t ucTransparent = pDraw->ucTransparent;
144+
for (x=0; x<pDraw->iWidth; x++)
145+
if (s[x] != ucTransparent) {
146+
p = &pPal[s[x] * 3];
147+
r = p[0] >> BRIGHT_SHIFT; g = p[1] >> BRIGHT_SHIFT; b = p[2] >> BRIGHT_SHIFT;
148+
SEGMENT.setPixelColorXY(x, y, RGBW32(r,g,b,0));
149+
}
115150
}
116-
busses.show();
151+
152+
else
153+
for (x=0; x<pDraw->iWidth; x++) {
154+
p = &pPal[s[x] * 3];
155+
r = p[0] >> BRIGHT_SHIFT; g = p[1] >> BRIGHT_SHIFT; b = p[2] >> BRIGHT_SHIFT;
156+
SEGMENT.setPixelColorXY(x, y, RGBW32(r,g,b,0));
157+
}
158+
159+
if (pDraw->y == pDraw->iHeight-1) // last line has been decoded, display the image
160+
strip.show();
117161
}
118162

119-
void pov_image() {
163+
uint16_t mode_pov_image(void) {
120164
const char * filepath = SEGMENT.name;
121-
int rc = png.open(filepath, openFile, closeFile, readPNG, seekPNG, pngDraw);
122-
if (rc == PNG_SUCCESS) {
123-
if (png.getWidth() != SEGLEN) return;
165+
int rc = png.open(filepath, openFile, closeFile, readPNG, seekPNG, pngPOV);
166+
if (rc == PNG_SUCCESS && png.getWidth() == SEGLEN) {
124167
rc = png.decode(NULL, 0);
125168
png.close();
126-
return;
169+
return FRAMETIME;
127170
}
128171

129172
gif.begin(GIF_PALETTE_RGB888);
130-
rc = gif.open(filepath, openFile, closeFile, readGIF, seekGIF, gifDraw);
131-
if (rc) {
132-
if (gif.getCanvasWidth() != SEGLEN) return;
173+
rc = gif.open(filepath, openFile, closeFile, readGIF, seekGIF, gifPOV);
174+
if (rc && gif.getCanvasWidth() == SEGLEN) {
133175
while (gif.playFrame(true, NULL)) {}
134176
gif.close();
177+
return FRAMETIME;
135178
}
179+
return FRAMETIME;
136180
}
137181

138-
uint16_t mode_pov_image(void) {
139-
pov_image();
182+
uint16_t mode_2d_image(void) {
183+
const char * filepath = SEGMENT.name;
184+
int rc = png.open(filepath, openFile, closeFile, readPNG, seekPNG, png2D);
185+
if (rc == PNG_SUCCESS && png.getWidth() * png.getHeight() == SEGLEN) {
186+
rc = png.decode(NULL, 0);
187+
png.close();
188+
return FRAMETIME;
189+
}
190+
191+
gif.begin(GIF_PALETTE_RGB888);
192+
rc = gif.open(filepath, openFile, closeFile, readGIF, seekGIF, gif2D);
193+
if (rc && gif.getCanvasWidth() * gif.getCanvasHeight() == SEGLEN) {
194+
while (gif.playFrame(true, NULL)) {}
195+
gif.close();
196+
return FRAMETIME;
197+
}
140198
return FRAMETIME;
141199
}
142200

143-
class PovDisplayUsermod : public Usermod
201+
class ImgDisplayUsermod : public Usermod
144202
{
145203
protected:
146204
bool enabled = false; //WLEDMM
@@ -150,6 +208,7 @@ class PovDisplayUsermod : public Usermod
150208
public:
151209
void setup() {
152210
strip.addEffect(FX_MODE_POV_IMAGE, &mode_pov_image, _data_FX_MODE_POV_IMAGE);
211+
strip.addEffect(FX_MODE_2D_IMAGE, &mode_2d_image, _data_FX_MODE_2D_IMAGE);
153212
initDone=true;
154213
}
155214

wled00/usermods_list.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@
197197
#include "../usermods/pwm_outputs/usermod_pwm_outputs.h"
198198
#endif
199199

200+
200201
#ifdef USERMOD_LDR_DUSK_DAWN
201202
#include "../usermods/LDR_Dusk_Dawn_v2/usermod_LDR_Dusk_Dawn_v2.h"
202203
#endif
@@ -205,6 +206,10 @@
205206
#include "../usermods/pov_display/usermod_pov_display.h"
206207
#endif
207208

209+
#ifdef USERMOD_IMG_DISPLAY
210+
#include "../usermods/img_display/usermod_img_display.h"
211+
#endif
212+
208213
#ifdef USERMOD_STAIRCASE_WIPE
209214
#include "../usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h"
210215
#endif
@@ -395,4 +400,8 @@ void registerUsermods()
395400
#ifdef USERMOD_POV_DISPLAY
396401
usermods.add(new PovDisplayUsermod());
397402
#endif
403+
404+
#ifdef USERMOD_IMG_DISPLAY
405+
usermods.add(new ImgDisplayUsermod());
406+
#endif
398407
}

0 commit comments

Comments
 (0)