PROCESSING IMAGE...

this may take a while, please be patient

DK CONVERTER


Conversion Parameters
You have Converted 0 images!
Thank you for using DK Converter!

Utility Code

This code is essential for drawing the image.
Paste it before the generated image code.
You only need to paste this once per program.
// Utility code for DK converter. It can also draw normal pixel arts, at an optimized speed. [

// stores cached pixel art graphics buffers
var _pixelArtCache = {};

// is it an array?
function isArray(a) {
    return Array.isArray(a);
}

// is it a PImage or similar object?
function isPImage(obj) {
    if (!obj) { return false; }
    try {
        return (typeof obj.width === "number") || (typeof obj.get === "function");
    } catch (e) {
        return false;
    }
}

// is it an RLE frame (array of strings)?
function isRLEFrame(frame) {
    return isArray(frame) && frame.length > 0 && typeof frame[0] === "string";
}

// build a cache key for pixel art rendering
function buildCacheKey(data, frameIndex, pixelSize, colorMap) {
    var prefix = "";
    try {
        prefix = JSON.stringify(data);
    } catch (e) {
        prefix = String(data);
    }

    var cmap = "";
    try {
        cmap = JSON.stringify(colorMap);
    } catch (e2) {
        cmap = String(colorMap);
    }

    return prefix + "|" + String(frameIndex) + "|" + String(pixelSize) + "|" + cmap;
}

// Clear the entire pixel art cache
function clearPixelArtCache() {
    _pixelArtCache = {};
}

// Invalidate a specific pixel art cache entry
function invalidatePixelArtCacheFor(data, frameIndex, pixelSize, colorMap) {
    var key = buildCacheKey(data, frameIndex, pixelSize, colorMap);
    if (_pixelArtCache[key]) {
        delete _pixelArtCache[key];
    }
}

// Decode a single RLE row string into an array of characters
function decodeRLERow(row) {
    var out = [];
    if (!row) { return out; }
    var i = 0;
    var n = row.length;

    while (i < n) {
        var ch = row.charAt(i);

        // skip digits (should not happen at this point)
        if (ch >= '0' && ch <= '9') {
            i++;
            continue;
        }

        // advance past the char
        i++;
        // collect digits (if any) to form the count
        var numStr = "";
        while (i < n) {
            var d = row.charAt(i);
            if (d < '0' || d > '9') { break; }
            numStr += d;
            i++;
        }

        var count = numStr.length ? parseInt(numStr, 10) : 1;

        for (var k = 0; k < count; k++) {
            out.push(ch);
        }
    }

    return out;
}

// Decode an RLE image (array of RLE row strings) into a 2D array of characters
function decodeRLEImage(lines) {
    var pixels = [];
    for (var y = 0; y < lines.length; y++) {
        pixels[y] = decodeRLERow(lines[y] || "");
    }
    return pixels;
}

// Check if a frame has any visible color based on the color map
function frameHasVisibleColor(frameData, colorMap) {
    if (!frameData) { return false; }
    for (var i = 0; i < frameData.length; i++) {
        var row = frameData[i];
        if (!row) { continue; }
        // check each character in the row
        for (var k = 0; k < row.length; k++) {
            var ch = row[k];
            if (ch !== "-" && colorMap && colorMap[ch] !== undefined) {
                return true;
            }
        }
    }
    return false;
}

// Draw decoded pixel data to a graphics buffer
function drawDecodedToGraphics(g, px, pixelSize, palette) {
    // Attempt to disable smoothing to keep crisp edges
    try {
        // idk if this actually works in KA
        if (typeof g.noSmooth === "function") { g.noSmooth(); }
    } catch (e) { }

    // ensure corner alignment
    try {
        if (typeof g.rectMode === "function") { g.rectMode(CORNER); }
    } catch (e2) { }

    g.noStroke();

    for (var y = 0; y < px.length; y++) {
        var row = px[y] || [];
        var x = 0;
        while (x < row.length) {
            var ch = row[x];
            var start = x;
            x++;
            while (x < row.length && row[x] === ch) { x++; }
            var run = x - start;

            if (ch === "-" || ch === null || ch === undefined) {
                // transparent pixel, skip
                continue;
            }

            var col = palette && palette[ch];
            if (!col) {
                // unmapped symbol, skip
                continue;
            }

            // compute rectangle coordinates
            var x1 = round(start * pixelSize);
            var x2 = round((start + run) * pixelSize);
            var y1 = round(y * pixelSize);
            var y2 = round((y + 1) * pixelSize);

            var gw = x2 - x1;
            var gh = y2 - y1;

            if (gw <= 0 || gh <= 0) { continue; }

            if (isArray(col)) {
                if (col.length === 4) {
                    g.fill(col[0], col[1], col[2], col[3]);
                } else {
                    g.fill(col[0], col[1], col[2]);
                }
            } else {
                g.fill(col);
            }

            g.rect(x1, y1, gw, gh);
        }
    }
}

// Main renderer
function drawHugePixelArt(startX, startY, pixelSize, canvasData, colorMap, frame) {
    // tiny safety margin for buffer sizing, but not used for drawing
    var sizeMargin = 1; 
    noStroke();

    // IMAGE PATHS first
    if (isArray(canvasData) && canvasData.length > 0 && isPImage(canvasData[0])) {
        if (frame === undefined) { frame = 1; }
        frame = Math.floor(frame);
        var idx = ((frame - 1) % canvasData.length + canvasData.length) % canvasData.length;
        var img = canvasData[idx];
        if (!img) { return; }

        var w = (typeof img.width === "number") ? img.width : (img.getWidth ? img.getWidth() : 0);
        var h = (typeof img.height === "number") ? img.height : (img.getHeight ? img.getHeight() : 0);

        image(img, startX, startY, round(w * pixelSize), round(h * pixelSize));
        return;
    }

    if (isPImage(canvasData)) {
        var w2 = (typeof canvasData.width === "number") ? canvasData.width : (canvasData.getWidth ? canvasData.getWidth() : 0);
        var h2 = (typeof canvasData.height === "number") ? canvasData.height : (canvasData.getHeight ? canvasData.getHeight() : 0);

        image(canvasData, startX, startY, round(w2 * pixelSize), round(h2 * pixelSize));
        return;
    }

    // RLE PATH
    var isFrames = isArray(canvasData) && canvasData.length > 0 && isRLEFrame(canvasData[0]);

    var data;
    var frameIndex = 0;

    if (isFrames) {
        if (frame === undefined) { frame = 1; }
        frame = Math.floor(frame);

        var idx2 = ((frame - 1) % canvasData.length + canvasData.length) % canvasData.length;

        var attempts = 0;
        var chosenIndex = idx2;
        while (attempts < canvasData.length) {
            var candidate = canvasData[chosenIndex];
            if (frameHasVisibleColor(candidate, colorMap)) {
                break;
            }
            chosenIndex = (chosenIndex - 1 + canvasData.length) % canvasData.length;
            attempts++;
        }

        data = canvasData[chosenIndex];
        frameIndex = chosenIndex;
    } else {
        if (!isArray(canvasData) || !isRLEFrame(canvasData)) {
            return;
        }
        data = canvasData;
        frameIndex = 0;
    }

    if (!data || data.length === 0) { return; }

    var cacheKey = buildCacheKey(data, frameIndex, pixelSize, colorMap);

    if (!_pixelArtCache[cacheKey]) {
        // decode fully (2D char array)
        var decoded = decodeRLEImage(data);

        // compute max cols and rows
        var maxCols = 0;
        for (var r = 0; r < decoded.length; r++) {
            var ln = decoded[r] ? decoded[r].length : 0;
            if (ln > maxCols) { maxCols = ln; }
        }
        var rows = decoded.length;

        var gw = max(1, round(maxCols * pixelSize) + sizeMargin);
        var gh = max(1, round(rows * pixelSize) + sizeMargin);

        var g = createGraphics(gw, gh, P2D);
        g.background(0, 0, 0, 0);

        // ensure corner alignment and crisp edges
        try {
            if (typeof g.rectMode === "function") { g.rectMode(CORNER); }
            if (typeof g.noSmooth === "function") { g.noSmooth(); }
        } catch (e3) { }
        
        g.noStroke();
        
        // draw to graphics buffer
        drawDecodedToGraphics(g, decoded, pixelSize, colorMap);

        _pixelArtCache[cacheKey] = g;
    }
    // let's light this candle
    image(_pixelArtCache[cacheKey], startX, startY);
}

// ]

Contact us at realdigitsofpi@gmail.com