This commit is contained in:
Your Name
2025-03-30 19:31:36 +02:00
parent 5bf9586000
commit fb389bec03
17 changed files with 194 additions and 380 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,194 @@
// -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
//
// Example how to display an image, including animated images using
// ImageMagick. For a full utility that does a few more things, have a look
// at the led-image-viewer in ../utils
//
// Showing an image is not so complicated, essentially just copy all the
// pixels to the canvas. How to get the pixels ? In this example we're using
// the graphicsmagick library as universal image loader library that
// can also deal with animated images.
// You can of course do your own image loading or use some other library.
//
// This requires an external dependency, so install these first before you
// can call `make image-example`
// sudo apt-get update
// sudo apt-get install libgraphicsmagick++-dev libwebp-dev -y
// make image-example
/*
pour compiler:
g++ -I/var/www/moduleair_pro_4g/matrix/include -L/var/www/moduleair_pro_4g/matrix/lib /var/www/moduleair_pro_4g/matrix/imageScreen/test_image.cc -o /var/www/moduleair_pro_4g/matrix/imageScreen/test_image -lrgbmatrix
g++ -I/var/www/moduleair_pro_4g/matrix/include -L/var/www/moduleair_pro_4g/matrix/lib /var/www/moduleair_pro_4g/matrix/imageScreen/test_image.cc -o /var/www/moduleair_pro_4g/matrix/imageScreen/test_image -lrgbmatrix `GraphicsMagick++-config --cppflags --libs`
pour lancer:
sudo /var/www/moduleair_pro_4g/matrix/imageScreen/test_image /var/www/moduleair_pro_4g/matrix/imageScreen/ModuleAir128x64.png
*/
#include "led-matrix.h"
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <exception>
#include <Magick++.h>
#include <magick/image.h>
using rgb_matrix::Canvas;
using rgb_matrix::RGBMatrix;
using rgb_matrix::FrameCanvas;
// Make sure we can exit gracefully when Ctrl-C is pressed.
volatile bool interrupt_received = false;
static void InterruptHandler(int signo) {
interrupt_received = true;
}
using ImageVector = std::vector<Magick::Image>;
// Given the filename, load the image and scale to the size of the
// matrix.
// // If this is an animated image, the resutlting vector will contain multiple.
static ImageVector LoadImageAndScaleImage(const char *filename,
int target_width,
int target_height) {
ImageVector result;
ImageVector frames;
try {
readImages(&frames, filename);
} catch (std::exception &e) {
if (e.what())
fprintf(stderr, "%s\n", e.what());
return result;
}
if (frames.empty()) {
fprintf(stderr, "No image found.");
return result;
}
// Animated images have partial frames that need to be put together
if (frames.size() > 1) {
Magick::coalesceImages(&result, frames.begin(), frames.end());
} else {
result.push_back(frames[0]); // just a single still image.
}
for (Magick::Image &image : result) {
image.scale(Magick::Geometry(target_width, target_height));
}
return result;
}
// Copy an image to a Canvas. Note, the RGBMatrix is implementing the Canvas
// interface as well as the FrameCanvas we use in the double-buffering of the
// animted image.
void CopyImageToCanvas(const Magick::Image &image, Canvas *canvas) {
const int offset_x = 0, offset_y = 0; // If you want to move the image.
// Copy all the pixels to the canvas.
for (size_t y = 0; y < image.rows(); ++y) {
for (size_t x = 0; x < image.columns(); ++x) {
const Magick::Color &c = image.pixelColor(x, y);
if (c.alphaQuantum() < 256) {
canvas->SetPixel(x + offset_x, y + offset_y,
ScaleQuantumToChar(c.redQuantum()),
ScaleQuantumToChar(c.greenQuantum()),
ScaleQuantumToChar(c.blueQuantum()));
}
}
}
}
// An animated image has to constantly swap to the next frame.
// We're using double-buffering and fill an offscreen buffer first, then show.
void ShowAnimatedImage(const ImageVector &images, RGBMatrix *matrix) {
FrameCanvas *offscreen_canvas = matrix->CreateFrameCanvas();
while (!interrupt_received) {
for (const auto &image : images) {
if (interrupt_received) break;
CopyImageToCanvas(image, offscreen_canvas);
offscreen_canvas = matrix->SwapOnVSync(offscreen_canvas);
usleep(image.animationDelay() * 10000); // 1/100s converted to usec
}
}
}
int usage(const char *progname) {
fprintf(stderr, "Usage: %s [led-matrix-options] <image-filename>\n",
progname);
rgb_matrix::PrintMatrixFlags(stderr);
return 1;
}
int main(int argc, char *argv[]) {
Magick::InitializeMagick(*argv);
// Check if a filename was provided
if (argc != 2) {
fprintf(stderr, "Usage: %s <image-filename>\n", argv[0]);
return 1;
}
const char *filename = argv[1];
// Initialize with hardcoded defaults for your specific hardware
RGBMatrix::Options defaults;
defaults.hardware_mapping = "moduleair_pinout";
defaults.rows = 64;
defaults.cols = 128;
defaults.chain_length = 1;
defaults.parallel = 1;
defaults.row_address_type = 3;
defaults.show_refresh_rate = true;
defaults.brightness = 100;
defaults.pwm_bits = 1;
defaults.panel_type = "FM6126A";
defaults.disable_hardware_pulsing = false;
// Set up runtime options (still needed)
rgb_matrix::RuntimeOptions runtime_opt;
runtime_opt.gpio_slowdown = 4; // Adjust if needed for your Pi model
runtime_opt.daemon = 0;
runtime_opt.drop_privileges = 0; // Set to 1 if not running as root
// Handle Ctrl+C to exit gracefully
signal(SIGTERM, InterruptHandler);
signal(SIGINT, InterruptHandler);
// Create the matrix with our defaults
RGBMatrix *matrix = RGBMatrix::CreateFromOptions(defaults, runtime_opt);
if (matrix == NULL) {
fprintf(stderr, "Failed to create matrix\n");
return 1;
}
// Load and process the image
ImageVector images = LoadImageAndScaleImage(filename,
matrix->width(),
matrix->height());
// Display the image(s)
switch (images.size()) {
case 0: // failed to load image
fprintf(stderr, "Failed to load image\n");
break;
case 1: // single image to show
CopyImageToCanvas(images[0], matrix);
while (!interrupt_received) sleep(1); // Until Ctrl-C is pressed
break;
default: // animation with multiple frames
ShowAnimatedImage(images, matrix);
break;
}
// Clean up
matrix->Clear();
delete matrix;
return 0;
}

View File

View File

Binary file not shown.

View File

@@ -1,69 +0,0 @@
/*
__ __ _ _____ ____ _____ __
| \/ | / \|_ _| _ \|_ _\ \/ /
| |\/| | / _ \ | | | |_) || | \ /
| | | |/ ___ \| | | _ < | | / \
|_| |_/_/ \_\_| |_| \_\___/_/\_\
Script to display a simple square on the matrix LED
sudo /var/www/moduleair_pro_4g/matrix/test_forms --led-no-hardware-pulse
Pour compiler:
g++ -Iinclude -Llib test_forms.cc -o test_forms -lrgbmatrix
Pour le lancer:
sudo /var/www/moduleair_pro_4g/matrix/test_forms
*/
#include "led-matrix.h"
#include "graphics.h"
#include <unistd.h>
using rgb_matrix::RGBMatrix;
using rgb_matrix::Canvas;
int main(int argc, char *argv[]) {
RGBMatrix::Options defaults;
defaults.hardware_mapping = "moduleair_pinout";
defaults.rows = 64;
defaults.cols = 128;
defaults.chain_length = 1;
defaults.parallel = 1;
defaults.row_address_type = 3;
defaults.show_refresh_rate = true;
defaults.brightness = 100;
defaults.pwm_bits = 1;
defaults.panel_type = "FM6126A";
defaults.disable_hardware_pulsing = false;
rgb_matrix::Color red(255, 0, 0); // Red color
rgb_matrix::Color bg_color(0, 0, 0); // Background color (black)
Canvas *canvas = RGBMatrix::CreateFromFlags(&argc, &argv, &defaults);
if (canvas == NULL)
return 1;
// Define the top-left corner of the square
int start_x = 10; // X coordinate
int start_y = 10; // Y coordinate
int square_size = 8; // Size of the square (8x8)
// Draw a filled square
for (int x = start_x; x < start_x + square_size; ++x) {
for (int y = start_y; y < start_y + square_size; ++y) {
canvas->SetPixel(x, y, red.r, red.g, red.b);
}
}
usleep(10000000); // Display for 10 seconds
// Clean up
canvas->Clear();
delete canvas;
return 0;
}

View File

@@ -1,136 +0,0 @@
/*
__ __ _ _____ ____ _____ __
| \/ | / \|_ _| _ \|_ _\ \/ /
| |\/| | / _ \ | | | |_) || | \ /
| | | |/ ___ \| | | _ < | | / \
|_| |_/_/ \_\_| |_| \_\___/_/\_\
Script to display a simple square on the matrix LED
Pour compiler:
g++ -Iinclude -Llib test_forms_infinite.cc -o test_forms_infinite -lrgbmatrix
Pour le lancer:
sudo /var/www/moduleair_pro_4g/matrix/test_forms_infinite
*/
#include "led-matrix.h"
#include "graphics.h"
#include <signal.h>
#include <unistd.h>
#include <vector>
#include <cstdlib> // For rand()
#include <ctime> // For time()
using rgb_matrix::RGBMatrix;
using rgb_matrix::Canvas;
using rgb_matrix::Color;
// Global flag that can be used to exit the loop
volatile bool running = true;
// Signal handler to catch Ctrl+C
static void InterruptHandler(int signo) {
running = false;
}
int main(int argc, char *argv[]) {
RGBMatrix::Options defaults;
defaults.hardware_mapping = "moduleair_pinout";
defaults.rows = 64;
defaults.cols = 128;
defaults.chain_length = 1;
defaults.parallel = 1;
defaults.row_address_type = 3;
defaults.show_refresh_rate = true;
defaults.brightness = 100;
defaults.pwm_bits = 1;
defaults.panel_type = "FM6126A";
defaults.disable_hardware_pulsing = false;
// Set up signal handler for clean exit
signal(SIGTERM, InterruptHandler);
signal(SIGINT, InterruptHandler);
// Seed the random number generator
srand(time(NULL));
Canvas *canvas = RGBMatrix::CreateFromFlags(&argc, &argv, &defaults);
if (canvas == NULL)
return 1;
// Get canvas dimensions for position constraints
int canvas_width = canvas->width();
int canvas_height = canvas->height();
// Square properties
int square_size = 8; // Size of the square (8x8)
int current_x = 10; // Initial X position
int current_y = 10; // Initial Y position
// Create an array of colors to cycle through
std::vector<Color> colors = {
Color(255, 0, 0), // Red
Color(0, 255, 0), // Green
Color(0, 0, 255), // Blue
Color(255, 255, 0), // Yellow
Color(0, 255, 255), // Cyan
Color(255, 0, 255), // Magenta
Color(255, 255, 255), // White
Color(255, 127, 0), // Orange
Color(127, 0, 255) // Purple
};
int color_index = 0;
time_t last_change = time(NULL);
// Draw initial square
Color current_color = colors[color_index];
for (int x = current_x; x < current_x + square_size; ++x) {
for (int y = current_y; y < current_y + square_size; ++y) {
canvas->SetPixel(x, y, current_color.r, current_color.g, current_color.b);
}
}
// Run indefinitely until interrupted
while (running) {
// Check if it's time to change color and position (every 2 seconds)
time_t now = time(NULL);
if (now - last_change >= 2) {
// Clear the previous square
for (int x = current_x; x < current_x + square_size; ++x) {
for (int y = current_y; y < current_y + square_size; ++y) {
canvas->SetPixel(x, y, 0, 0, 0); // Clear to black
}
}
// Move to the next color
color_index = (color_index + 1) % colors.size();
current_color = colors[color_index];
// Generate new random position, ensuring the square stays fully on screen
current_x = rand() % (canvas_width - square_size);
current_y = rand() % (canvas_height - square_size);
// Draw the square with the new color at the new position
for (int x = current_x; x < current_x + square_size; ++x) {
for (int y = current_y; y < current_y + square_size; ++y) {
canvas->SetPixel(x, y, current_color.r, current_color.g, current_color.b);
}
}
last_change = now;
}
// Small sleep to prevent using 100% CPU
usleep(100000); // 100ms sleep
}
// Clean up when interrupted
canvas->Clear();
delete canvas;
return 0;
}

Binary file not shown.

View File

@@ -1,100 +0,0 @@
/*
__ __ _ _____ ____ _____ __
| \/ | / \|_ _| _ \|_ _\ \/ /
| |\/| | / _ \ | | | |_) || | \ /
| | | |/ ___ \| | | _ < | | / \
|_| |_/_/ \_\_| |_| \_\___/_/\_\
Script to display a simple square on the matrix LED
sudo /var/www/moduleair_pro_4g/matrix/test_forms_noFail --led-no-hardware-pulse
Pour compiler:
g++ -Iinclude -Llib test_forms_noFail.cc -o test_forms_noFail -lrgbmatrix
*/
#include "led-matrix.h"
#include "graphics.h"
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
using rgb_matrix::RGBMatrix;
using rgb_matrix::Canvas;
volatile bool running = true;
static void InterruptHandler(int signo) {
running = false;
}
int main(int argc, char *argv[]) {
RGBMatrix::Options defaults;
defaults.hardware_mapping = "moduleair_pinout";
defaults.rows = 64;
defaults.cols = 128;
defaults.chain_length = 1;
defaults.parallel = 1;
defaults.row_address_type = 3;
defaults.show_refresh_rate = true;
defaults.brightness = 100;
defaults.pwm_bits = 1;
defaults.panel_type = "FM6126A";
defaults.disable_hardware_pulsing = false;
// Set up signal handlers for clean exit
signal(SIGTERM, InterruptHandler);
signal(SIGINT, InterruptHandler);
// Try creating the matrix with a few attempts
Canvas *canvas = NULL;
int attempts = 0;
while (canvas == NULL && attempts < 3) {
canvas = RGBMatrix::CreateFromFlags(&argc, &argv, &defaults);
if (canvas == NULL) {
fprintf(stderr, "Creating canvas failed, attempt %d/3. Retrying...\n", attempts + 1);
attempts++;
usleep(500000); // Wait 500ms before retry
}
}
if (canvas == NULL) {
fprintf(stderr, "Failed to create canvas after multiple attempts.\n");
return 1;
}
// Always clear the canvas first to reset any previous state
canvas->Clear();
usleep(100000); // Small delay after clearing
rgb_matrix::Color red(255, 0, 0); // Red color
// Define the top-left corner of the square
int start_x = 10; // X coordinate
int start_y = 10; // Y coordinate
int square_size = 8; // Size of the square (8x8)
// Draw a filled square
for (int x = start_x; x < start_x + square_size; ++x) {
for (int y = start_y; y < start_y + square_size; ++y) {
canvas->SetPixel(x, y, red.r, red.g, red.b);
}
}
// Keep running until signaled
int seconds = 0;
while (running && seconds < 10) {
sleep(1);
seconds++;
}
// Always ensure we clean up
canvas->Clear();
usleep(100000); // Small delay after clearing
delete canvas;
fprintf(stderr, "Display completed successfully.\n");
return 0;
}

Binary file not shown.

View File

@@ -1,75 +0,0 @@
/*
__ __ _ _____ ____ _____ __
| \/ | / \|_ _| _ \|_ _\ \/ /
| |\/| | / _ \ | | | |_) || | \ /
| | | |/ ___ \| | | _ < | | / \
|_| |_/_/ \_\_| |_| \_\___/_/\_\
Script to display a simple text on the matrix LED
sudo /var/www/moduleair_pro_4g/matrix/test_text
Pour compiler:
g++ -Iinclude -Llib test_text.cc -o test_text -lrgbmatrix
Pour lancer:
sudo /var/www/moduleair_pro_4g/matrix/test_text
*/
#include "led-matrix.h"
#include "graphics.h"
#include <unistd.h>
#include <string.h>
using rgb_matrix::RGBMatrix;
using rgb_matrix::Canvas;
int main(int argc, char *argv[]) {
RGBMatrix::Options defaults;
defaults.hardware_mapping = "moduleair_pinout";
defaults.rows = 64;
defaults.cols = 128;
defaults.chain_length = 1;
defaults.parallel = 1;
defaults.row_address_type=3;
defaults.show_refresh_rate = true;
defaults.brightness = 100;
defaults.pwm_bits = 1;
defaults.panel_type = "FM6126A";
defaults.disable_hardware_pulsing = false;
rgb_matrix::Color color1(255, 0, 0); // Red color for the first line
rgb_matrix::Color color2(0, 0, 255); // Blue color for the second line
rgb_matrix::Color bg_color(0, 0, 0); // Background color (black)
int letter_spacing = 0;
Canvas *canvas = RGBMatrix::CreateFromFlags(&argc, &argv, &defaults);
if (canvas == NULL)
return 1;
// Load font
rgb_matrix::Font font;
if (!font.LoadFont("fonts/8x13.bdf")) return 1;
// Define text for each line
const char *line1 = "Plouf Les amis!";
const char *line2 = "Salut a tous!";
// Display first line with color1
int x = 0;
int y1 = font.baseline(); // First line position
rgb_matrix::DrawText(canvas, font, x, y1, color1, &bg_color, line1, letter_spacing);
// Display second line with color2
int y2 = y1 + font.height(); // Second line position, just below the first line
rgb_matrix::DrawText(canvas, font, x, y2, color2, &bg_color, line2, letter_spacing);
usleep(4000000); // Display for 4 seconds
// Clean up
canvas->Clear();
delete canvas;
return 0;
}

View File