here’s an ascii art generator that pastes the right characters in the right excel cells to form an image. What if we want to increase the horizontal resolution by having more than 1 character o “word” per cell. Let’s say we have a 512 x 64 image, and we want to have 8 characters per cell. Therefore we use 64 horizontal cells, and we pack 8 “pixels” in each cell, one for each character: check out the c++ code:
void BitmapToASCII(const char* base64Data,
const mxl::Variant& characterMatrix,
mxl::Variant& result,
const int* width_height_bpp,
const int column)
{
// Unpack the parameters because fucking excel VBA doesn’t like more than 5 argument
const uint32_t width = width_height_bpp[0];
const uint32_t height = width_height_bpp[1];
const uint32_t bits_per_pixel = width_height_bpp[2];
// Use std::vector for unpacked pixel data
std::vector<int> outArray(width * height);
ProcessImageData(base64Data, outArray.data(), width, height, bits_per_pixel);
#if defined(_WIN32) || defined(_WIN64)
// Assuming characterMatrix is a VARIANT containing a 2D SAFEARRAY
SAFEARRAY* characterMap = V_ARRAY(&characterMatrix);
LONG ubound1, lbound1, ubound2, lbound2;
SafeArrayGetUBound(characterMap, 1, &ubound1);
SafeArrayGetLBound(characterMap, 1, &lbound1);
SafeArrayGetUBound(characterMap, 2, &ubound2);
SafeArrayGetLBound(characterMap, 2, &lbound2);
size_t rows = ubound1 - lbound1 + 1;
size_t columns = ubound2 - lbound2 + 1;
if (rows < 1 || columns < 1) return; // Check for valid character map
// Define the bounds for the 2D array (ASCII art)
sab[0].lLbound = 0; sab[0].cElements = height;
sab[1].lLbound = 0; sab[1].cElements = width;
// Create the SAFEARRAY for the ASCII art
SAFEARRAY* asciiArt = SafeArrayCreate(VT_VARIANT, 2, sab);
#else
// Mac-specific code using MinXL
// Convert characterMapVariant to mxl::Arraymxl::Variant
mxl::Arraymxl::Variant characterMap = characterMatrix;
// Assuming the character map is a 2D array with meaningful rows and arbitrary columns
size_t rows = characterMap.Rows();
size_t columns = characterMap.Columns(); // Assuming we need to handle multiple columns now
if (rows < 1 || columns < 1) return; // Check for valid character map
// Create a 2D mxl::Variant array to hold the ASCII art
mxl::Array<mxl::Variant> asciiArt(height, width); // Note the dimensions
#endif
for (uint32_t y = 0; y < height; ++y) {
for (uint32_t x = 0; x < width; ++x) {
int pixelIndex = x * height + y;
int pixelValue = outArray[pixelIndex];
size_t rowIndex = std::min(size_t(pixelValue * (rows - 1) / 255), rows - 1);
#if defined(PLATFORM_WINDOWS)
VARIANT vWord;
VariantInit(&vWord);
// Assuming the character map is a 2D array of BSTRs, fetch the string
LONG indices[] = { static_cast<LONG>(rowIndex + lbound1), static_cast<LONG>(column + lbound2) };
SafeArrayGetElement(characterMap, indices, &vWord);
// Set the ASCII art cell to the word
indices[0] = y; indices[1] = x;
SafeArrayPutElement(asciiArt, indices, &vWord);
#else
mxl::String word = characterMap(rowIndex, column);
asciiArt(y, x) = word;
#endif
#if defined(PLATFORM_WINDOWS)
// Assign the populated SAFEARRAY to the result VARIANT
VariantClear(&result); // Clear the result VARIANT first
result.vt = VT_ARRAY | VT_VARIANT; // Specify that this is an array of VARIANTs
result.parray = asciiArt;
#else
// Assign the populated 2D array to the result
result = std::move(asciiArt);
#endif
}