Closed zogs closed 1 year ago
Hi zogs,
as you can see in the docs or in the source code, there is only a prototype with an uint8_t pointer bool drawImage(const uint8_t *buf, ...
which needs the width and height as a parameter.
http.getStream()
returns a reference of WiFiClient
, http.getStreamPtr()
returns a pointer to WiFiClient
and the class WiFiClient
has no member named peekBuffer
, so none of these functions will work here.
If you just want to display the picture on your screen, you can use this:
display.drawImage("https://placehold.co/1200x820.png", 0, 0, 1200, 820)
Fyi, the drawBitmapFromWeb() function has a prototype like int drawBitmapFromWeb(WiFiClient *s, ...
, do not mix that up.
There are some very good examples for pictures from web, this link is for Inkplate10: Inkplate10_Show_Pictures_From_Web
I hope you'll find what you need.
Hello @zogs!
As @DHueter mentioned, there is an example on how to get an image from the web and display it on the Inkplate. You could use HttpClient, but you can also use a drawImage() function, just send the link of the image, set the x and y coordinates where You wanna draw the image, and select if you want the image to be dithered or not
bool drawImage(const char *path, int x, int y, bool dither = 1, bool invert = 0);
Example code for the drawImage function and example for the httpClient.
As far as I can see, You are missing
http.getStream().setNoDelay(true);
http.getStream().setTimeout(1);
and also You need to use drawBitmapFromWeb() function, instead of drawImage(), but by using drawBitmapFromWeb() You only can display .bmp files not .png.
Hope this helps.
Thanks for answers.
I know i can use directly drawImage(url) but i dont want that. I need a fine handling of http response code. That is why i am using HttpClient ... Maybe there is another solution here ?
So as i understand there is no way to get the buffer from HttpClient ? That's a pitty since there is a drawImage() prototype that handle a uint8_t *buf ...
I can not use .bmp format for the moment... but i will look if it is possible.
uint8_t *buf in the drawImage() function is used to write the image from the internal memory (RAM) of the ESP32 (similar to drawBitmap3Bit() but with dithering and invert option).
Unfortunately, there is no way to get HTTP code from the drawImage function. Maybe in the some update of the library, we add an option to get HTTP status or at least to be able to send HTTPCilent object.
One solution that comes to my mind is to first read HTTP response code and see if the code is ok, and if it is try to load the image using drawImage() function.
Actually this is what i do currently ! but this makes the image downloaded twice so it's far from optimal, and an error can still occur during the second call ....
So, maybe i can first download the image to RAM, then feed drawImage() with it ? Would that be possible ?
http.getString() will return the HTTP response body and despite the name it's not always a proper string.
With getStream however you could write it into a RAM buffer - if you have enough - or on the SDCard and load it from there.
The library also has a few examples and functions to cut this short. Here are two links that might help as inspiration.
My bad, I mixed up the functions, sorry.
drawImage() with uint8_t *buf will draw the image directly into the buffer of the epaper. The idea is to use this function to draw the image on display using generated code from the Inkplate Image Converter in 1 bit mode. The only way to use HTTP and draw the image on the screen is to first download the image with downloadFile() function, save it in the memory, decode it, convert RGB into 4 bit grayscale pixel and using drawPixel push the pixels into framebuffer of the epaper. A drawJpegFromWebAtPosition() and bool drawJpegFromBuffer() functions are a good starting point on how to do that.
Thank you both for pointing me to the right direction !
Here's the final code:
http.begin(url);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK)
{
int32_t size = http.getSize();
int32_t len = size;
if(size > 0)
{
uint8_t *buffer = (uint8_t *)ps_malloc(size);
uint8_t *buffPtr = buffer;
uint8_t buff[512] = {0};
WiFiClient *stream = http.getStreamPtr();
while (http.connected() && (len > 0 || len == -1))
{
size_t size = stream->available();
if (size)
{
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
memcpy(buffPtr, buff, c);
if (len > 0)
len -= c;
buffPtr += c;
}
else if (len == -1)
{
len = 0;
}
}
display.drawJpegFromBuffer(buffer, size, 0, 0, false, false);
free(buffer);
}
else {
display.setCursor(400, 350);
display.println("Invalid response length "+ String(size) +" (HTTP "+ String(httpCode) +")");
}
}
else {
display.setCursor(500, 350);
display.println("HTTP error" + String(httpCode) + "...");
}
display.display();
Good job! 😄
I run it on the Inkplate10 and it works like a charm!
And if you don't mind and if it's ok for you, we are planning to use this code as part of the example in Inkplate library, so that in the future people do not need to write this code from the scratch.
Of course please do !
I pasted the code here for reference if someone stumble upon this thread, it's even better if it becomes an official example 😄
The issue is closed because the problem is solved and there is no more activity
Hi, I can't figure out how to use the response buffer from a httpClient to feed drawImage()
I tried to look at HttpClient.h and WifiClient.h and tried many things but can't find my way... I'm a beginner in c++ so i think it's time to call for help !
This is the code i tried: