Closed nicholas-gh closed 2 years ago
I'm wondering why it works at all :) The JPEGDRAW callback can send you any "shape" of rectangle because it's decoding MCUs which can be 8x8, 16x8, 8x16 or 16x16. It fits as many as it can in the 4k internal buffer for each call. This means that you can get a callback for the left half of a 16-pixel row followed by a call for the right half. This won't print properly in this case.
I think it would be wise to allocate a buffer big enough for the whole decoded image, decode into that buffer and then print it in one shot.
Yes, awesome - that was it. JPEGDraw
callback now copies in to a large buffer, and when it's all decoded, then I sent it to the printer.
It's very hard coded now, since I didn't make it cope will variable answers for how much it needs to pad each row (since the camera image isn't the ideal size for the printer rows). I don't really want to show exactly how lazy I did it, but I will since maybe it helps the next person...
uint8_t fullBuffer[(PRINTER_WIDTH * (VGA_HEIGHT / 2)) / 8] = {1};
int JPEGDraw(JPEGDRAW *pDraw)
{
int i, iCount;
uint8_t *s = (uint8_t *)pDraw->pPixels;
Serial.printf("We got a pixel block of %d x %d\n", pDraw->iWidth, pDraw->iHeight);
// The output is inverted, so flip the bits as we copy to fullBuffer
// Hard coded for what we get from the camera jpg decoding (4 full rows)
// TODO cope if we got something else
for (i = 0; i < 40; i++)
fullBuffer[fullBuffer_i++] = ~s[i];
fullBuffer_i += 8; // pad row
for (i = 40; i < 80; i++)
fullBuffer[fullBuffer_i++] = ~s[i];
fullBuffer_i += 8; // pad row
for (i = 80; i < 120; i++)
fullBuffer[fullBuffer_i++] = ~s[i];
fullBuffer_i += 8; // pad row
for (i = 120; i < 160; i++)
fullBuffer[fullBuffer_i++] = ~s[i];
fullBuffer_i += 8; // pad row
Serial.printf("Current fullBuffer_i is %d of %d\n", fullBuffer_i, sizeof(fullBuffer));
return 1; // Continue decode
}
But it works well. I'll do some more work and maybe have it print sideways to get more useful pixels out.
Many thanks!
PS: well, it kind of works; the image printed seems to be a previous captured image. I assume I'm missing something on the esp-camera end there! (Edit: https://www.esp32.com/viewtopic.php?t=24566 but no answers so far)
I'm hoping that users of this library might have practical experience which can tell me if I'm doing something wrong in code, or if my printer is faulty. I don't find similar issues on the web, so also hoping a discussion here might help future people with the same problem. Many thanks for any thoughts on what might be wrong!
It fed paper fine until I started printing images captured using esp32-camera; >90% of the time images from esp32-camera do not print/feed the paper correctly. If I go back afterwards and use the PeriPage app on a phone, or use the example jpg printing from the Thermal_Printer library, it sometimes feeds and sometimes does not. Using 'banner' feature in the PeriPage app does seem to feed OK.
It feels like maybe my esp32-camera images are overheating something which causes the paper feed to slide instead of actually feeding the paper. The images look OK if I gently pull the paper while it's printing. I can make a video of this if helpful.
I've experimented with a few different jpeg_quality, and also different image sizes from the camera, and different scaling (half, quarter, none).
My code (not really mine so much, I simply combined together a few examples):