Please bookmark this page to avoid losing your image tool!

Image Map Boundary Label Editor

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
/**
 * Processes a map image to find and replace specific boundary abbreviations with their full names.
 * This function uses Optical Character Recognition (OCR) to perform the following replacements:
 * - "Brgy_bnd" is changed to "Barangay Boundary"
 * - "Mun_bnd" is changed to "Municipal Boundary"
 *
 * It dynamically loads the Tesseract.js library to analyze the image text.
 * The function identifies the target text, erases it by drawing a white rectangle
 * over it (assuming a plain background), and then writes the new, longer text in its place,
 * attempting to center it relative to the original text's position.
 *
 * Note: The other parts of the description ("Trick and marks are replaced inside the map frame...", etc.)
 * are interpreted as context about the expected map layout, not as actions to be performed by this function.
 * Automating the detection and geometric manipulation of map elements like ticks and coordinate labels
 * is a highly complex computer vision task that is beyond the scope of this implementation.
 *
 * @param {HTMLImageElement} originalImg The source image object to process.
 * @returns {Promise<HTMLCanvasElement>} A Promise that resolves with a new canvas element
 *   containing the modified image. If an error occurs, it returns a canvas with the
 *   original image and an error message drawn on it.
 */
async function processImage(originalImg) {
    // Helper function to dynamically load a script if it's not already present.
    const loadScript = (url) => {
        return new Promise((resolve, reject) => {
            const existingScript = document.querySelector(`script[src="${url}"]`);
            if (existingScript) {
                // If script tag exists but Tesseract is not loaded, wait for it.
                if (typeof Tesseract === 'undefined') {
                     existingScript.addEventListener('load', () => resolve());
                     existingScript.addEventListener('error', (e) => reject(new Error(`Script load error for ${url}`)));
                } else {
                    resolve(); // Already loaded.
                }
                return;
            }
            const script = document.createElement('script');
            script.src = url;
            script.onload = () => resolve();
            script.onerror = () => reject(new Error(`Script load error for ${url}`));
            document.head.appendChild(script);
        });
    };

    try {
        // Load the Tesseract.js library for OCR.
        await loadScript('https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js');

        const canvas = document.createElement('canvas');
        // Use willReadFrequently for performance optimization with OCR.
        const ctx = canvas.getContext('2d', { willReadFrequently: true });
        canvas.width = originalImg.naturalWidth;
        canvas.height = originalImg.naturalHeight;
        ctx.drawImage(originalImg, 0, 0);

        const replacements = {
            'Brgy_bnd': 'Barangay Boundary',
            'Mun_bnd': 'Municipal Boundary',
        };

        // Create a Tesseract worker, run OCR, and then terminate the worker.
        const worker = await Tesseract.createWorker('eng');
        const { data: { words } } = await worker.recognize(canvas);

        for (const word of words) {
            const recognizedText = word.text.trim();
            
            if (replacements[recognizedText]) {
                const newText = replacements[recognizedText];
                const oldBbox = word.bbox;

                // Estimate font style from the original text's bounding box.
                const oldHeight = oldBbox.y1 - oldBbox.y0;
                const oldWidth = oldBbox.x1 - oldBbox.x0;
                const fontSize = oldHeight * 0.85; // Heuristic for font size.
                ctx.font = `bold ${fontSize}px Arial`;
                ctx.textBaseline = 'top';
                ctx.textAlign = 'left';

                // Measure the new text to get its width.
                const newMetrics = ctx.measureText(newText);
                const newWidth = newMetrics.width;

                // Calculate the position for the new centered text.
                const oldCenterX = oldBbox.x0 + oldWidth / 2;
                const newX = oldCenterX - newWidth / 2;
                const newY = oldBbox.y0;

                // Determine the total area to clear, covering both old and new text.
                const clearX = Math.min(oldBbox.x0, newX);
                const clearWidth = Math.max(oldBbox.x1, newX + newWidth) - clearX;

                // Erase the area. Assumes a white background, common for map legends.
                ctx.fillStyle = 'white';
                ctx.fillRect(
                    clearX - 2, // Add a small margin for safety
                    oldBbox.y0 - 2,
                    clearWidth + 4,
                    oldHeight + 4
                );
                
                // Draw the new text. Assumes black text color.
                ctx.fillStyle = 'black';
                ctx.fillText(newText, newX, newY);
            }
        }

        await worker.terminate();
        return canvas;

    } catch (error) {
        console.error("Image processing failed:", error);
        // If an error occurs, return the original image on a canvas with an error message.
        const errorCanvas = document.createElement('canvas');
        errorCanvas.width = originalImg.naturalWidth;
        errorCanvas.height = originalImg.naturalHeight;
        const errorCtx = errorCanvas.getContext('2d');
        errorCtx.drawImage(originalImg, 0, 0);
        errorCtx.fillStyle = 'rgba(255, 0, 0, 0.8)';
        errorCtx.font = 'bold 16px Arial';
        errorCtx.textAlign = 'center';
        errorCtx.fillText('Error: Could not process image.', errorCanvas.width / 2, 30);
        return errorCanvas;
    }
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Image Map Boundary Label Editor is a tool designed for processing map images to enhance their readability by replacing abbreviated boundary labels with their full names. Using Optical Character Recognition (OCR), the tool identifies specific text in the image, such as ‘Brgy_bnd’, and replaces it with ‘Barangay Boundary’, or ‘Mun_bnd’ with ‘Municipal Boundary’. This feature is particularly useful for users such as cartographers, urban planners, or educators who want to make map information clearer for presentation, publication, or educational purposes. The tool utilizes a canvas-based approach to modify the original image while ensuring that the new text is neatly centered and visually aligned with the original labels.

Leave a Reply

Your email address will not be published. Required fields are marked *