Added support for jpeg(stb) and webp(libwebp)
This commit is contained in:
@@ -14,15 +14,16 @@ find_package(DPP REQUIRED)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SQLITE3 REQUIRED sqlite3)
|
||||
pkg_check_modules(CAIRO REQUIRED cairo)
|
||||
pkg_check_modules(WEBP REQUIRED libwebpdecoder)
|
||||
|
||||
# Link the pre-installed DPP package.
|
||||
target_link_libraries(${PROJECT_NAME} ${DPP_LIBRARIES} ${SQLITE3_LIBRARIES}
|
||||
${CAIRO_LIBRARIES})
|
||||
${CAIRO_LIBRARIES} ${WEBP_LIBRARIES})
|
||||
|
||||
# Include the DPP directories.
|
||||
target_include_directories(
|
||||
${PROJECT_NAME} PRIVATE ${DPP_INCLUDE_DIR} ${SQLITE3_INCLUDE_DIR}
|
||||
${CAIRO_INCLUDE_DIR})
|
||||
${CAIRO_INCLUDE_DIR} ${WEBP_INCLUDE_DIR})
|
||||
|
||||
# Set C++ version
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 20
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#include "../Common.hpp"
|
||||
#include "../Utility/CairoTools.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <dpp/dispatcher.h>
|
||||
#include <dpp/dpp.h>
|
||||
#include <dpp/guild.h>
|
||||
@@ -25,11 +27,22 @@ void commandGenerateReport(const dpp::slashcommand_t &event,
|
||||
bot.request(
|
||||
file.url, dpp::http_method::m_get,
|
||||
[event, &bot, fileType](const dpp::http_request_completion_t &result) {
|
||||
std::string responseData = GenerateReportImage(
|
||||
fileType->second(
|
||||
result.body), // Image itself processed for cario to handle
|
||||
std::get<std::string>(event.get_parameter("headline")));
|
||||
auto imageAsSurface = fileType->second(result.body);
|
||||
if (imageAsSurface == nullptr) {
|
||||
event.edit_response("Failed to load the background image :(");
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't forget that its only funny if it is all in upper case
|
||||
std::string headline =
|
||||
std::get<std::string>(event.get_parameter("headline"));
|
||||
|
||||
// Never seen this method before but looks awesome
|
||||
std::transform(headline.begin(), headline.end(), headline.data(),
|
||||
::toupper);
|
||||
|
||||
std::string responseData =
|
||||
GenerateReportImage(imageAsSurface, headline);
|
||||
dpp::message response(event.command.channel_id, "");
|
||||
response.add_file("report.png", responseData);
|
||||
event.edit_response(response);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "CairoTools.hpp"
|
||||
#include <cctype>
|
||||
|
||||
std::string GenerateReportImage(cairo_surface_t *background,
|
||||
std::string headline) {
|
||||
|
@@ -1,5 +1,11 @@
|
||||
#include "CairoTools.hpp"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
#include <webp/decode.h>
|
||||
#include <webp/types.h>
|
||||
|
||||
std::unordered_map<std::string,
|
||||
std::function<cairo_surface_t *(const std::string &)>>
|
||||
supportedImageFileTypes{{"image/png", pngToCairoSurface},
|
||||
@@ -31,9 +37,63 @@ cairo_surface_t *pngToCairoSurface(const std::string &data) {
|
||||
return cairo_image_surface_create_from_png_stream(
|
||||
cairoReadPNGdata, const_cast<std::string *>(&data));
|
||||
}
|
||||
cairo_surface_t *jpegToCairoSurface(std::string data) {
|
||||
return cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 300, 200);
|
||||
|
||||
///
|
||||
/// JPEG and WEBP
|
||||
///
|
||||
|
||||
inline cairo_surface_t *swizzleToBGRA(unsigned char *data, int width,
|
||||
int height, bool isjpeg = true) {
|
||||
// AI code start - Reviewed, looks solid
|
||||
cairo_surface_t *surface =
|
||||
cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
|
||||
unsigned char *surface_data = cairo_image_surface_get_data(surface);
|
||||
int stride = cairo_image_surface_get_stride(surface);
|
||||
|
||||
// Convert RGB to BGRA
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
unsigned char *src =
|
||||
data + (y * width + x) * (isjpeg ? 3 : 4); // Swizzling
|
||||
unsigned char *dst = surface_data + y * stride + x * 4; // Still swizzling
|
||||
dst[0] = src[2]; // B
|
||||
dst[1] = src[1]; // G
|
||||
dst[2] = src[0]; // R
|
||||
dst[3] = src[3]; // A
|
||||
}
|
||||
}
|
||||
cairo_surface_mark_dirty(surface);
|
||||
// AI code end
|
||||
return surface;
|
||||
}
|
||||
cairo_surface_t *webpToCairoSurface(std::string data) {
|
||||
return cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 300, 200);
|
||||
|
||||
cairo_surface_t *jpegToCairoSurface(const std::string &data) {
|
||||
int width, height, channels;
|
||||
unsigned char *imgData = stbi_load_from_memory(
|
||||
reinterpret_cast<const unsigned char *>(data.data()), data.size(), &width,
|
||||
&height, &channels, 3 // Channel count
|
||||
);
|
||||
|
||||
if (imgData == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto image = swizzleToBGRA(imgData, width, height);
|
||||
stbi_image_free(imgData);
|
||||
return image;
|
||||
}
|
||||
|
||||
cairo_surface_t *webpToCairoSurface(const std::string &data) {
|
||||
int width, height;
|
||||
unsigned char *imgData =
|
||||
WebPDecodeRGBA(reinterpret_cast<const uint8_t *>(data.data()),
|
||||
data.size(), &width, &height);
|
||||
|
||||
if (imgData == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto image = swizzleToBGRA(imgData, width, height, false);
|
||||
WebPFree(imgData);
|
||||
return image;
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#define REPORT_HEIGHT 1200
|
||||
#define REPORT_HEIGHT_OFFSET 200
|
||||
#define REPORT_TEXT_START_X 40
|
||||
#define REPORT_TEXT_JUMP_Y 120
|
||||
#define REPORT_TEXT_JUMP_Y 125
|
||||
#define REPORT_TEXT_FONT_SIZE 120.0
|
||||
#define REPORT_TEXT_LENGTH 26
|
||||
#define REPORT_RESOURCE_BUMPER_PATH "./assets/report_bumper.png"
|
||||
@@ -23,8 +23,8 @@ cairo_status_t cairoOutputAsPNGStream(void *closure, const unsigned char *data,
|
||||
unsigned int length);
|
||||
|
||||
cairo_surface_t *pngToCairoSurface(const std::string &data);
|
||||
cairo_surface_t *jpegToCairoSurface(std::string data);
|
||||
cairo_surface_t *webpToCairoSurface(std::string data);
|
||||
cairo_surface_t *jpegToCairoSurface(const std::string &data);
|
||||
cairo_surface_t *webpToCairoSurface(const std::string &data);
|
||||
|
||||
extern std::unordered_map<std::string,
|
||||
std::function<cairo_surface_t *(const std::string &)>>
|
||||
|
Reference in New Issue
Block a user