5 static const char *
const TAG =
"online_image";
9 #ifdef USE_ONLINE_IMAGE_PNG_SUPPORT 14 namespace online_image {
24 return ((color.
r >> 2) + (color.
g >> 1) + (color.
b >> 2)) & 0x80;
28 uint32_t download_buffer_size)
29 : Image(nullptr, 0, 0, type),
31 download_buffer_(download_buffer_size),
34 fixed_height_(height) {
40 Image::draw(x, y, display, color_on, color_off);
48 ESP_LOGD(TAG,
"Deallocating old buffer...");
74 ESP_LOGD(TAG,
"Allocating new buffer of %d Bytes...", new_size);
81 ESP_LOGD(TAG,
"New size: (%d, %d)", width, height);
83 #if defined(USE_ESP8266) 85 int max_block = ESP.getMaxFreeBlockSize();
86 #elif defined(USE_ESP32) 87 int max_block = heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL);
91 ESP_LOGE(TAG,
"allocation failed. Biggest block in heap: %d Bytes", max_block);
100 ESP_LOGW(TAG,
"Image already being updated.");
103 ESP_LOGI(TAG,
"Updating image");
109 ESP_LOGE(TAG,
"Download failed.");
116 if (http_code == HTTP_CODE_NOT_MODIFIED) {
121 if (http_code != HTTP_CODE_OK) {
122 ESP_LOGE(TAG,
"HTTP result: %d", http_code);
128 ESP_LOGD(TAG,
"Starting download");
129 size_t total_size = this->
downloader_->content_length;
131 #ifdef USE_ONLINE_IMAGE_PNG_SUPPORT 133 this->
decoder_ = esphome::make_unique<PngDecoder>(
this);
135 #endif // ONLINE_IMAGE_PNG_SUPPORT 138 ESP_LOGE(TAG,
"Could not instantiate decoder. Image format unsupported.");
143 this->
decoder_->prepare(total_size);
144 ESP_LOGI(TAG,
"Downloading image");
153 ESP_LOGD(TAG,
"Image fully downloaded");
162 ESP_LOGE(TAG,
"Downloader not instantiated; cannot download");
172 ESP_LOGE(TAG,
"Error when decoding image.");
184 ESP_LOGE(TAG,
"Buffer not allocated!");
188 ESP_LOGE(TAG,
"Tried to paint a pixel (%d,%d) outside the image!", x, y);
192 switch (this->
type_) {
194 const uint32_t width_8 = ((this->
width_ + 7u) / 8u) * 8u;
195 const uint32_t pos = x + y * width_8;
197 this->
buffer_[pos / 8u] |= (0x80 >> (pos % 8u));
199 this->
buffer_[pos / 8u] &= ~(0x80 >> (pos % 8u));
204 uint8_t gray =
static_cast<uint8_t
>(0.2125 * color.
r + 0.7154 * color.
g + 0.0721 * color.
b);
209 if (color.
w < 0x80) {
218 this->
buffer_[pos + 0] =
static_cast<uint8_t
>((col565 >> 8) & 0xFF);
219 this->
buffer_[pos + 1] =
static_cast<uint8_t
>(col565 & 0xFF);
234 if (color.
b == 1 && color.
r == 0 && color.
g == 0) {
237 if (color.
w < 0x80) {
261 if ((url.length() < 8) || (url.find(
"http") != 0) || (url.find(
"://") == std::string::npos)) {
262 ESP_LOGE(TAG,
"URL is invalid and/or must be prefixed with 'http://' or 'https://'");
bool resize_(int width, int height)
bool has_transparency() const
bool validate_url_(const std::string &url)
void draw_pixel_(int x, int y, Color color)
Draw a pixel into the buffer.
std::shared_ptr< HttpContainer > get(std::string url)
int buffer_width_
Actual width of the current image.
void add_on_finished_callback(std::function< void()> &&callback)
static uint16_t color_to_565(Color color, ColorOrder color_order=ColorOrder::COLOR_ORDER_RGB)
const int fixed_height_
height requested on configuration, or 0 if non specified.
std::unique_ptr< ImageDecoder > decoder_
void set_url(const std::string &url)
Set the URL to download the image from.
int buffer_height_
Actual height of the current image.
void IRAM_ATTR HOT delay_microseconds_safe(uint32_t us)
Delay for the given amount of microseconds, possibly yielding to other processes during the wait...
const int fixed_width_
width requested on configuration, or 0 if non specified.
DownloadBuffer download_buffer_
ESPHOME_ALWAYS_INLINE bool auto_resize_() const
std::shared_ptr< http_request::HttpContainer > downloader_
void add_on_error_callback(std::function< void()> &&callback)
esphome::http_request::HttpRequestComponent * parent_
bool is_color_on(const Color &color)
size_t free_capacity() const
CallbackManager< void()> download_error_callback_
OnlineImage(const std::string &url, int width, int height, ImageFormat format, image::ImageType type, uint32_t buffer_size)
Construct a new OnlineImage object.
const uint8_t * data_start_
void deallocate(T *p, size_t n)
uint8_t * data(size_t offset=0)
CallbackManager< void()> download_finished_callback_
void release()
Release the buffer storing the image.
int get_position_(int x, int y) const
image::Image * placeholder_
void draw(int x, int y, display::Display *display, Color color_on, Color color_off) override
Implementation of SPI Controller mode.
const ImageFormat format_
void draw(int x, int y, display::Display *display, Color color_on, Color color_off) override
ImageFormat
Format that the image is encoded with.
uint32_t get_buffer_size_() const