From 6d62606f6b15fced4a100d954d8c9f23d60d4c27 Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Thu, 29 Apr 2021 15:04:04 +0200 Subject: [PATCH 01/10] Added Image::setImageFromMemory --- library/include/borealis/views/image.hpp | 9 ++++++++ library/lib/views/image.cpp | 29 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/library/include/borealis/views/image.hpp b/library/include/borealis/views/image.hpp index 9108025f7..ba48fcba8 100644 --- a/library/include/borealis/views/image.hpp +++ b/library/include/borealis/views/image.hpp @@ -95,6 +95,15 @@ class Image : public View */ void setImageFromFile(std::string path); + /** + * Sets the image from a memory buffer. The data read has to be + * the same as if the image would've been read from a file. + * + * See NanoVG documentation and the Image class documentation for the + * list of supported image formats. + */ + void setImageFromMemory(unsigned char* data, int numData); + /** * Sets the scaling type for this image. * diff --git a/library/lib/views/image.cpp b/library/lib/views/image.cpp index 00424f3fa..8cf0ab51c 100644 --- a/library/lib/views/image.cpp +++ b/library/lib/views/image.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace brls { @@ -280,6 +281,34 @@ void Image::setImageFromFile(std::string path) this->invalidate(); } +void Image::setImageFromMemory(unsigned char* data, int numData) +{ + NVGcontext* vg = Application::getNVGContext(); + + // Free the old texture if necessary + if (this->texture != 0) + nvgDeleteImage(vg, this->texture); + + // Load the new texture + int flags = this->getImageFlags(); + this->texture = nvgCreateImageMem(vg, flags, data, numData); + + if (this->texture == 0) + { + std::stringstream addr; + addr << (void*)data; + + fatal("Cannot load image from memory (" + std::to_string(numData) + " bytes at 0x" + addr.str() + ")"); + } + + int width, height; + nvgImageSize(vg, this->texture, &width, &height); + this->originalImageWidth = (float)width; + this->originalImageHeight = (float)height; + + this->invalidate(); +} + void Image::setScalingType(ImageScalingType scalingType) { this->scalingType = scalingType; From 04fe37bcfb2b6a0d07176c95ce3cd0f552c2f972 Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Mon, 3 May 2021 07:46:20 +0200 Subject: [PATCH 02/10] Don't need address in error message --- library/lib/views/image.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/library/lib/views/image.cpp b/library/lib/views/image.cpp index 8cf0ab51c..1e0a431fa 100644 --- a/library/lib/views/image.cpp +++ b/library/lib/views/image.cpp @@ -19,7 +19,6 @@ #include #include #include -#include namespace brls { @@ -294,12 +293,7 @@ void Image::setImageFromMemory(unsigned char* data, int numData) this->texture = nvgCreateImageMem(vg, flags, data, numData); if (this->texture == 0) - { - std::stringstream addr; - addr << (void*)data; - - fatal("Cannot load image from memory (" + std::to_string(numData) + " bytes at 0x" + addr.str() + ")"); - } + fatal("Cannot load image from memory (" + std::to_string(numData) + " bytes)"); int width, height; nvgImageSize(vg, this->texture, &width, &height); From 9f46f991518206e610cb8cb7b054b0b009634d78 Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Thu, 6 May 2021 16:34:51 +0200 Subject: [PATCH 03/10] Changed nvgCreateImageMem to nvgCreateImageRGBA and implemented a small demo --- demo/dynamic_image.cpp | 74 ++++++++++++++++++++++++ demo/dynamic_image.hpp | 34 +++++++++++ demo/main.cpp | 2 + library/include/borealis/views/image.hpp | 9 ++- library/lib/views/image.cpp | 13 +++-- resources/xml/tabs/components.xml | 15 +++++ resources/xml/views/dynamic_image.xml | 20 +++++++ 7 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 demo/dynamic_image.cpp create mode 100644 demo/dynamic_image.hpp create mode 100644 resources/xml/views/dynamic_image.xml diff --git a/demo/dynamic_image.cpp b/demo/dynamic_image.cpp new file mode 100644 index 000000000..ac5a32fd2 --- /dev/null +++ b/demo/dynamic_image.cpp @@ -0,0 +1,74 @@ +/* + Copyright 2019 WerWolv + Copyright 2019 p-sam + Copyright 2020-2021 natinusala + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "dynamic_image.hpp" + +DynamicImage::DynamicImage() +{ + // Load the XML file and inflate ourself with its content + this->inflateFromXMLRes("xml/views/dynamic_image.xml"); + + // Forward Image XML attributes + this->forwardXMLAttribute("scalingType", this->image); + this->forwardXMLAttribute("image", this->image); + this->forwardXMLAttribute("focusUp", this->image); + this->forwardXMLAttribute("focusRight", this->image); + this->forwardXMLAttribute("focusDown", this->image); + this->forwardXMLAttribute("focusLeft", this->image); + this->forwardXMLAttribute("imageWidth", this->image, "width"); + this->forwardXMLAttribute("imageHeight", this->image, "height"); + + // Register a click action for this button + BRLS_REGISTER_CLICK_BY_ID("image", this->onImageClicked); +} + +bool DynamicImage::onImageClicked(brls::View* view) +{ + // Retrieve the image size + int height = this->image->getHeight(); + int width = this->image->getWidth(); + + // Generate the pixel data for a new image + size_t bufferSize = height * width * 4; // 4 bytes per pixel (RGBA) + unsigned char* imageData = (unsigned char*)calloc(1, bufferSize); + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + memset(&imageData[(y * width + x) * 4 + 3], (unsigned char)255, sizeof(unsigned char)); // Alpha + memset(&imageData[(y * width + x) * 4 + 2], (unsigned char)((y+x)*255/(height+width)), sizeof(unsigned char)); // Blue + memset(&imageData[(y * width + x) * 4 + 1], (unsigned char)(x*255/width), sizeof(unsigned char)); // Green + memset(&imageData[(y * width + x) * 4 + 0], (unsigned char)(y*255/height), sizeof(unsigned char)); // Red + } + } + + // Display the image + this->image->setImageFromMemory(imageData, width, height); + + // Free the image buffer + free(imageData); + + return true; +} + +brls::View* DynamicImage::create() +{ + // Called by the XML engine to create a new DynamicImage + return new DynamicImage(); +} diff --git a/demo/dynamic_image.hpp b/demo/dynamic_image.hpp new file mode 100644 index 000000000..859629dbb --- /dev/null +++ b/demo/dynamic_image.hpp @@ -0,0 +1,34 @@ +/* + Copyright 2019 WerWolv + Copyright 2019 p-sam + Copyright 2020-2021 natinusala + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#pragma once + +#include + +class DynamicImage : public brls::Box +{ + public: + DynamicImage(); + + static brls::View* create(); + + private: + BRLS_BIND(brls::Image, image, "image"); + + bool onImageClicked(brls::View* View); +}; diff --git a/demo/main.cpp b/demo/main.cpp index a27bd956b..1dfd6ee85 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -27,6 +27,7 @@ #include #include "captioned_image.hpp" +#include "dynamic_image.hpp" #include "components_tab.hpp" #include "main_activity.hpp" #include "recycling_list_tab.hpp" @@ -60,6 +61,7 @@ int main(int argc, char* argv[]) brls::Application::registerXMLView("CaptionedImage", CaptionedImage::create); brls::Application::registerXMLView("RecyclingListTab", RecyclingListTab::create); brls::Application::registerXMLView("ComponentsTab", ComponentsTab::create); + brls::Application::registerXMLView("DynamicImage", DynamicImage::create); // Add custom values to the theme brls::getLightTheme().addColor("captioned_image/caption", nvgRGB(2, 176, 183)); diff --git a/library/include/borealis/views/image.hpp b/library/include/borealis/views/image.hpp index ba48fcba8..d4a2de9a4 100644 --- a/library/include/borealis/views/image.hpp +++ b/library/include/borealis/views/image.hpp @@ -96,13 +96,12 @@ class Image : public View void setImageFromFile(std::string path); /** - * Sets the image from a memory buffer. The data read has to be - * the same as if the image would've been read from a file. + * Sets the image from a memory buffer. The data should be a + * raw four-channel (RGBA) pixel array of the size width*height*4. * - * See NanoVG documentation and the Image class documentation for the - * list of supported image formats. + * See the example implementation dynamic_image in the demo. */ - void setImageFromMemory(unsigned char* data, int numData); + void setImageFromMemory(const unsigned char* data, int width, int height); /** * Sets the scaling type for this image. diff --git a/library/lib/views/image.cpp b/library/lib/views/image.cpp index 1e0a431fa..34ea809ae 100644 --- a/library/lib/views/image.cpp +++ b/library/lib/views/image.cpp @@ -280,7 +280,7 @@ void Image::setImageFromFile(std::string path) this->invalidate(); } -void Image::setImageFromMemory(unsigned char* data, int numData) +void Image::setImageFromMemory(const unsigned char* data, int width, int height) { NVGcontext* vg = Application::getNVGContext(); @@ -290,13 +290,14 @@ void Image::setImageFromMemory(unsigned char* data, int numData) // Load the new texture int flags = this->getImageFlags(); - this->texture = nvgCreateImageMem(vg, flags, data, numData); - + this->texture = nvgCreateImageRGBA(vg, width, height, flags, data); + if (this->texture == 0) - fatal("Cannot load image from memory (" + std::to_string(numData) + " bytes)"); + { + brls::Logger::error("Cannot load image from memory (" + std::to_string(width) + "x" + std::to_string(height) + ")"); + return; + } - int width, height; - nvgImageSize(vg, this->texture, &width, &height); this->originalImageWidth = (float)width; this->originalImageHeight = (float)height; diff --git a/resources/xml/tabs/components.xml b/resources/xml/tabs/components.xml index 063547337..5113c822c 100644 --- a/resources/xml/tabs/components.xml +++ b/resources/xml/tabs/components.xml @@ -209,6 +209,21 @@ + + + + + + diff --git a/resources/xml/views/dynamic_image.xml b/resources/xml/views/dynamic_image.xml new file mode 100644 index 000000000..34f327a24 --- /dev/null +++ b/resources/xml/views/dynamic_image.xml @@ -0,0 +1,20 @@ + + + + + + + From c0d748ba9b39f2889824b36f186495e1c17c0a25 Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Thu, 6 May 2021 16:47:56 +0200 Subject: [PATCH 04/10] Differentiated between setImageFromMemory and setImageFromRawData, as the first still might be useful for e.g. image files requested from the web --- demo/dynamic_image.cpp | 2 +- library/include/borealis/views/image.hpp | 11 ++++++++++- library/lib/views/image.cpp | 25 +++++++++++++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/demo/dynamic_image.cpp b/demo/dynamic_image.cpp index ac5a32fd2..73db0a8dc 100644 --- a/demo/dynamic_image.cpp +++ b/demo/dynamic_image.cpp @@ -59,7 +59,7 @@ bool DynamicImage::onImageClicked(brls::View* view) } // Display the image - this->image->setImageFromMemory(imageData, width, height); + this->image->setImageFromRawData(imageData, width, height); // Free the image buffer free(imageData); diff --git a/library/include/borealis/views/image.hpp b/library/include/borealis/views/image.hpp index d4a2de9a4..76f8b2262 100644 --- a/library/include/borealis/views/image.hpp +++ b/library/include/borealis/views/image.hpp @@ -95,13 +95,22 @@ class Image : public View */ void setImageFromFile(std::string path); + /** + * Sets the image from a memory buffer. The data read has to be + * the same as if the image would've been read from a file. + * + * See NanoVG documentation and the Image class documentation for the + * list of supported image formats. + */ + void setImageFromMemory(unsigned char* data, int numData); + /** * Sets the image from a memory buffer. The data should be a * raw four-channel (RGBA) pixel array of the size width*height*4. * * See the example implementation dynamic_image in the demo. */ - void setImageFromMemory(const unsigned char* data, int width, int height); + void setImageFromRawData(const unsigned char* data, int width, int height); /** * Sets the scaling type for this image. diff --git a/library/lib/views/image.cpp b/library/lib/views/image.cpp index 34ea809ae..ffb83727c 100644 --- a/library/lib/views/image.cpp +++ b/library/lib/views/image.cpp @@ -280,7 +280,30 @@ void Image::setImageFromFile(std::string path) this->invalidate(); } -void Image::setImageFromMemory(const unsigned char* data, int width, int height) +void Image::setImageFromMemory(unsigned char* data, int numData) +{ + NVGcontext* vg = Application::getNVGContext(); + + // Free the old texture if necessary + if (this->texture != 0) + nvgDeleteImage(vg, this->texture); + + // Load the new texture + int flags = this->getImageFlags(); + this->texture = nvgCreateImageMem(vg, flags, data, numData); + + if (this->texture == 0) + fatal("Cannot load image from memory"); + + int width, height; + nvgImageSize(vg, this->texture, &width, &height); + this->originalImageWidth = (float)width; + this->originalImageHeight = (float)height; + + this->invalidate(); +} + +void Image::setImageFromRawData(const unsigned char* data, int width, int height) { NVGcontext* vg = Application::getNVGContext(); From 38fcb807f823db179482bbec411aedc3467f25aa Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Tue, 18 May 2021 13:21:33 +0200 Subject: [PATCH 05/10] Renamed DynamicImage to RandomRGBAImage, added random image generation for demo, made label using i18n, included in meson.build --- demo/main.cpp | 4 +- ...ynamic_image.cpp => random_rgba_image.cpp} | 50 ++++++++++++------- ...ynamic_image.hpp => random_rgba_image.hpp} | 10 ++-- library/include/borealis/views/image.hpp | 6 +-- library/lib/views/image.cpp | 4 +- meson.build | 1 + resources/i18n/en-US/demo.json | 4 +- resources/xml/tabs/components.xml | 2 +- ...ynamic_image.xml => random_rgba_image.xml} | 2 +- 9 files changed, 50 insertions(+), 33 deletions(-) rename demo/{dynamic_image.cpp => random_rgba_image.cpp} (62%) rename demo/{dynamic_image.hpp => random_rgba_image.hpp} (83%) rename resources/xml/views/{dynamic_image.xml => random_rgba_image.xml} (85%) diff --git a/demo/main.cpp b/demo/main.cpp index 1dfd6ee85..1ba07456d 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -27,7 +27,7 @@ #include #include "captioned_image.hpp" -#include "dynamic_image.hpp" +#include "random_rgba_image.hpp" #include "components_tab.hpp" #include "main_activity.hpp" #include "recycling_list_tab.hpp" @@ -61,7 +61,7 @@ int main(int argc, char* argv[]) brls::Application::registerXMLView("CaptionedImage", CaptionedImage::create); brls::Application::registerXMLView("RecyclingListTab", RecyclingListTab::create); brls::Application::registerXMLView("ComponentsTab", ComponentsTab::create); - brls::Application::registerXMLView("DynamicImage", DynamicImage::create); + brls::Application::registerXMLView("RandomRGBAImage", RandomRGBAImage::create); // Add custom values to the theme brls::getLightTheme().addColor("captioned_image/caption", nvgRGB(2, 176, 183)); diff --git a/demo/dynamic_image.cpp b/demo/random_rgba_image.cpp similarity index 62% rename from demo/dynamic_image.cpp rename to demo/random_rgba_image.cpp index 73db0a8dc..5330de86a 100644 --- a/demo/dynamic_image.cpp +++ b/demo/random_rgba_image.cpp @@ -1,7 +1,5 @@ /* - Copyright 2019 WerWolv - Copyright 2019 p-sam - Copyright 2020-2021 natinusala + Copyright 2021 Jonathan Verbeek Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,12 +14,12 @@ limitations under the License. */ -#include "dynamic_image.hpp" +#include "random_rgba_image.hpp" -DynamicImage::DynamicImage() +RandomRGBAImage::RandomRGBAImage() { // Load the XML file and inflate ourself with its content - this->inflateFromXMLRes("xml/views/dynamic_image.xml"); + this->inflateFromXMLRes("xml/views/random_rgba_image.xml"); // Forward Image XML attributes this->forwardXMLAttribute("scalingType", this->image); @@ -37,38 +35,54 @@ DynamicImage::DynamicImage() BRLS_REGISTER_CLICK_BY_ID("image", this->onImageClicked); } -bool DynamicImage::onImageClicked(brls::View* view) +bool RandomRGBAImage::onImageClicked(brls::View* view) +{ + // Generate a new image + this->generateRandomImage(); + + return true; +} + +unsigned char interp(unsigned char src, unsigned char dst, float alpha) +{ + return src * (1.0 - alpha) + dst * alpha; +} + +void RandomRGBAImage::generateRandomImage() { // Retrieve the image size int height = this->image->getHeight(); int width = this->image->getWidth(); - // Generate the pixel data for a new image - size_t bufferSize = height * width * 4; // 4 bytes per pixel (RGBA) + // Allocate the RGBA image buffer + size_t bufferSize = height * width * 4; // 4 bytes per pixel (RGBA8888) unsigned char* imageData = (unsigned char*)calloc(1, bufferSize); + // Randomly generate two colors for a gradient + unsigned char color1[3] = { std::rand() % 255, std::rand() % 255, std::rand() % 255}; + unsigned char color2[3] = { std::rand() % 255, std::rand() % 255, std::rand() % 255}; + for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { - memset(&imageData[(y * width + x) * 4 + 3], (unsigned char)255, sizeof(unsigned char)); // Alpha - memset(&imageData[(y * width + x) * 4 + 2], (unsigned char)((y+x)*255/(height+width)), sizeof(unsigned char)); // Blue - memset(&imageData[(y * width + x) * 4 + 1], (unsigned char)(x*255/width), sizeof(unsigned char)); // Green - memset(&imageData[(y * width + x) * 4 + 0], (unsigned char)(y*255/height), sizeof(unsigned char)); // Red + // Set the pixel data + memset(&imageData[(y * width + x) * 4 + 3], (unsigned char)255, sizeof(unsigned char)); // Alpha + memset(&imageData[(y * width + x) * 4 + 2], (unsigned char)interp(color1[2], color2[2], (float)x/(float)width), sizeof(unsigned char)); // Blue + memset(&imageData[(y * width + x) * 4 + 1], (unsigned char)interp(color1[1], color2[1], (float)x/(float)width), sizeof(unsigned char)); // Green + memset(&imageData[(y * width + x) * 4 + 0], (unsigned char)interp(color1[0], color2[0], (float)x/(float)width), sizeof(unsigned char)); // Red } } // Display the image - this->image->setImageFromRawData(imageData, width, height); + this->image->setImageFromRGBA(imageData, width, height); // Free the image buffer free(imageData); - - return true; } -brls::View* DynamicImage::create() +brls::View* RandomRGBAImage::create() { // Called by the XML engine to create a new DynamicImage - return new DynamicImage(); + return new RandomRGBAImage(); } diff --git a/demo/dynamic_image.hpp b/demo/random_rgba_image.hpp similarity index 83% rename from demo/dynamic_image.hpp rename to demo/random_rgba_image.hpp index 859629dbb..c3f8d350c 100644 --- a/demo/dynamic_image.hpp +++ b/demo/random_rgba_image.hpp @@ -1,7 +1,5 @@ /* - Copyright 2019 WerWolv - Copyright 2019 p-sam - Copyright 2020-2021 natinusala + Copyright 2021 Jonathan Verbeek Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,10 +18,10 @@ #include -class DynamicImage : public brls::Box +class RandomRGBAImage : public brls::Box { public: - DynamicImage(); + RandomRGBAImage(); static brls::View* create(); @@ -31,4 +29,6 @@ class DynamicImage : public brls::Box BRLS_BIND(brls::Image, image, "image"); bool onImageClicked(brls::View* View); + + void generateRandomImage(); }; diff --git a/library/include/borealis/views/image.hpp b/library/include/borealis/views/image.hpp index 76f8b2262..4787d60e4 100644 --- a/library/include/borealis/views/image.hpp +++ b/library/include/borealis/views/image.hpp @@ -105,12 +105,12 @@ class Image : public View void setImageFromMemory(unsigned char* data, int numData); /** - * Sets the image from a memory buffer. The data should be a - * raw four-channel (RGBA) pixel array of the size width*height*4. + * Sets the image from a memory buffer. The data should be following the + * R8G8B8A8 pixel format. * * See the example implementation dynamic_image in the demo. */ - void setImageFromRawData(const unsigned char* data, int width, int height); + void setImageFromRGBA(const unsigned char* data, int width, int height); /** * Sets the scaling type for this image. diff --git a/library/lib/views/image.cpp b/library/lib/views/image.cpp index ffb83727c..0997f43fd 100644 --- a/library/lib/views/image.cpp +++ b/library/lib/views/image.cpp @@ -303,7 +303,7 @@ void Image::setImageFromMemory(unsigned char* data, int numData) this->invalidate(); } -void Image::setImageFromRawData(const unsigned char* data, int width, int height) +void Image::setImageFromRGBA(const unsigned char* data, int width, int height) { NVGcontext* vg = Application::getNVGContext(); @@ -317,7 +317,7 @@ void Image::setImageFromRawData(const unsigned char* data, int width, int height if (this->texture == 0) { - brls::Logger::error("Cannot load image from memory (" + std::to_string(width) + "x" + std::to_string(height) + ")"); + brls::Logger::error("Cannot create image from RGBA data (" + std::to_string(width) + "x" + std::to_string(height) + ")"); return; } diff --git a/meson.build b/meson.build index f2f43e276..e1200862f 100644 --- a/meson.build +++ b/meson.build @@ -11,6 +11,7 @@ demo_files = files( 'demo/main_activity.cpp', 'demo/captioned_image.cpp', + 'demo/random_rgba_image.cpp', 'demo/recycling_list_tab.cpp', 'demo/components_tab.cpp', diff --git a/resources/i18n/en-US/demo.json b/resources/i18n/en-US/demo.json index c5a99f1d7..e45041ab3 100644 --- a/resources/i18n/en-US/demo.json +++ b/resources/i18n/en-US/demo.json @@ -35,7 +35,9 @@ "images_original": "Original", "images_upscaled": "Upscaled", "images_stretched": "Stretched", - "images_cropped": "Cropped" + "images_cropped": "Cropped", + + "random_rgba_image": "Randomly generated RGBA (click to refresh)" }, "about": { diff --git a/resources/xml/tabs/components.xml b/resources/xml/tabs/components.xml index 5113c822c..8ba753ef4 100644 --- a/resources/xml/tabs/components.xml +++ b/resources/xml/tabs/components.xml @@ -216,7 +216,7 @@ alignItems="center" justifyContent="spaceEvenly"> - + text="@i18n/demo/components/random_rgba_image" /> From dd2011994981149770e22fddd1c82f3b1528cd29 Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Fri, 21 May 2021 11:17:53 +0200 Subject: [PATCH 06/10] Hardcode the size of the random rgba_image to 256x256 --- demo/random_rgba_image.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/demo/random_rgba_image.cpp b/demo/random_rgba_image.cpp index 5330de86a..a5f38a569 100644 --- a/demo/random_rgba_image.cpp +++ b/demo/random_rgba_image.cpp @@ -33,6 +33,9 @@ RandomRGBAImage::RandomRGBAImage() // Register a click action for this button BRLS_REGISTER_CLICK_BY_ID("image", this->onImageClicked); + + // Generate a new image + this->generateRandomImage(); } bool RandomRGBAImage::onImageClicked(brls::View* view) @@ -50,9 +53,9 @@ unsigned char interp(unsigned char src, unsigned char dst, float alpha) void RandomRGBAImage::generateRandomImage() { - // Retrieve the image size - int height = this->image->getHeight(); - int width = this->image->getWidth(); + // Size of the image to generate + int height = 256; + int width = 256; // Allocate the RGBA image buffer size_t bufferSize = height * width * 4; // 4 bytes per pixel (RGBA8888) From 5698d4795bc972ce68138900ce39d36e3cd7f9a6 Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Fri, 21 May 2021 11:22:11 +0200 Subject: [PATCH 07/10] Fixed "narrow conversion" warning --- demo/random_rgba_image.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/demo/random_rgba_image.cpp b/demo/random_rgba_image.cpp index a5f38a569..bfaf3e13d 100644 --- a/demo/random_rgba_image.cpp +++ b/demo/random_rgba_image.cpp @@ -62,8 +62,16 @@ void RandomRGBAImage::generateRandomImage() unsigned char* imageData = (unsigned char*)calloc(1, bufferSize); // Randomly generate two colors for a gradient - unsigned char color1[3] = { std::rand() % 255, std::rand() % 255, std::rand() % 255}; - unsigned char color2[3] = { std::rand() % 255, std::rand() % 255, std::rand() % 255}; + unsigned char color1[3] = { + static_cast(std::rand() % 255), + static_cast(std::rand() % 255), + static_cast(std::rand() % 255) + }; + unsigned char color2[3] = { + static_cast(std::rand() % 255), + static_cast(std::rand() % 255), + static_cast(std::rand() % 255) + }; for (int y = 0; y < height; y++) { From f7effeb810e3aa388c20fc144365acb7d51aad43 Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Wed, 26 May 2021 08:00:24 +0200 Subject: [PATCH 08/10] Added padding and changed size of random rgba image --- resources/xml/tabs/components.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/resources/xml/tabs/components.xml b/resources/xml/tabs/components.xml index 8ba753ef4..34f09a0e5 100644 --- a/resources/xml/tabs/components.xml +++ b/resources/xml/tabs/components.xml @@ -185,7 +185,8 @@ height="auto" axis="row" alignItems="center" - justifyContent="spaceEvenly"> + justifyContent="spaceEvenly" + marginBottom="30px" > + justifyContent="spaceEvenly" > + imageWidth="400px" + imageHeight="75px" + scalingType="stretch" /> From 6740d2575cb7e1d89daddeee76135a176b13a115 Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Wed, 15 Dec 2021 11:14:17 +0100 Subject: [PATCH 09/10] Made Image::setImageFromMemory's data buffer const too --- library/include/borealis/views/image.hpp | 2 +- library/lib/views/image.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/include/borealis/views/image.hpp b/library/include/borealis/views/image.hpp index 4787d60e4..cd0e92d93 100644 --- a/library/include/borealis/views/image.hpp +++ b/library/include/borealis/views/image.hpp @@ -102,7 +102,7 @@ class Image : public View * See NanoVG documentation and the Image class documentation for the * list of supported image formats. */ - void setImageFromMemory(unsigned char* data, int numData); + void setImageFromMemory(const unsigned char* data, int numData); /** * Sets the image from a memory buffer. The data should be following the diff --git a/library/lib/views/image.cpp b/library/lib/views/image.cpp index 0997f43fd..458c4cd36 100644 --- a/library/lib/views/image.cpp +++ b/library/lib/views/image.cpp @@ -280,7 +280,7 @@ void Image::setImageFromFile(std::string path) this->invalidate(); } -void Image::setImageFromMemory(unsigned char* data, int numData) +void Image::setImageFromMemory(const unsigned char* data, int numData) { NVGcontext* vg = Application::getNVGContext(); From 52c341f2c30f4f0c44969d036d34a948da33945e Mon Sep 17 00:00:00 2001 From: Jonathan Verbeek Date: Wed, 15 Dec 2021 11:34:40 +0100 Subject: [PATCH 10/10] nanovg expects a non-const data buffer in Image::setImageFromMemory but doesn't alter the data, so we don't have to expose the non-constness to borealis --- library/lib/views/image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/lib/views/image.cpp b/library/lib/views/image.cpp index 458c4cd36..170303ce0 100644 --- a/library/lib/views/image.cpp +++ b/library/lib/views/image.cpp @@ -290,7 +290,7 @@ void Image::setImageFromMemory(const unsigned char* data, int numData) // Load the new texture int flags = this->getImageFlags(); - this->texture = nvgCreateImageMem(vg, flags, data, numData); + this->texture = nvgCreateImageMem(vg, flags, (unsigned char*)data, numData); if (this->texture == 0) fatal("Cannot load image from memory");