Please bookmark this page to avoid losing your image tool!

Image Analysis For TV Damage Assessment

(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.
/**
 * Analyzes an image of a TV screen to detect common types of damage.
 * This function looks for dead/stuck pixels, solid horizontal/vertical lines, and large dark areas indicative of cracks.
 * It returns a new canvas with the original image and visual overlays highlighting potential issues.
 *
 * @param {Image} originalImg The source image object of the TV screen to analyze.
 * @param {number} stuckPixelSensitivity A value from 0 to 255. A pixel is considered potentially stuck/dead if its color channels are within this sensitivity value of pure black, red, green, or blue. A lower value is stricter. Default is 25.
 * @param {number} lineDetectionThreshold A value from 0.0 to 1.0. A row or column is flagged as a line issue if this proportion of its pixels are of a similar color. Default is 0.9 (90%).
 * @param {number} crackDarknessValue A value from 0 to 765 (255*3). A pixel is considered "dark" (part of a potential crack) if the sum of its R, G, and B values is less than this. Default is 45.
 * @param {number} crackAreaThreshold A value from 0.0 to 1.0. A 32x32 pixel block is flagged as a damaged area if this proportion of its pixels are "dark". Default is 0.95 (95%).
 * @returns {HTMLCanvasElement} A canvas element with the analysis results drawn on it.
 */
async function processImage(originalImg, stuckPixelSensitivity = 25, lineDetectionThreshold = 0.9, crackDarknessValue = 45, crackAreaThreshold = 0.95) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', {
        willReadFrequently: true
    });

    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;
    canvas.width = width;
    canvas.height = height;

    // Draw the original image to the canvas
    ctx.drawImage(originalImg, 0, 0, width, height);

    // Get the pixel data from the canvas
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;

    const issues = {
        pixels: [],
        lines: [],
        areas: []
    };
    const colorSimilarityTolerance = 20; // Max color distance for pixels to be considered "similar" in line detection

    // Helper function to get pixel color at a coordinate
    const getPixel = (x, y) => {
        const i = (y * width + x) * 4;
        return [data[i], data[i + 1], data[i + 2]];
    };

    // Helper function to calculate Euclidean distance between two colors
    const colorDiff = (c1, c2) => {
        return Math.sqrt(Math.pow(c1[0] - c2[0], 2) + Math.pow(c1[1] - c2[1], 2) + Math.pow(c1[2] - c2[2], 2));
    };

    // --- 1. Dead/Stuck Pixel Detection ---
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const i = (y * width + x) * 4;
            const r = data[i], g = data[i + 1], b = data[i + 2];
            const s = stuckPixelSensitivity;

            const isDead = (r < s && g < s && b < s);
            const isStuck = (r > 255 - s && g < s && b < s) || (r < s && g > 255 - s && b < s) || (r < s && g < s && b > 255 - s);

            if (isDead || isStuck) {
                // Heuristic: A true stuck/dead pixel should be significantly different from its neighbors
                let mismatchNeighbors = 0;
                let validNeighbors = 0;
                const pixelColor = [r, g, b];
                const neighborPositions = [ [x - 1, y], [x + 1, y], [x, y - 1], [x, y + 1]];

                for (const [nx, ny] of neighborPositions) {
                    if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
                        validNeighbors++;
                        if (colorDiff(pixelColor, getPixel(nx, ny)) > 50) {
                            mismatchNeighbors++;
                        }
                    }
                }
                if (validNeighbors > 0 && mismatchNeighbors / validNeighbors >= 0.75) {
                    issues.pixels.push({ x, y });
                }
            }
        }
    }

    // --- 2. Line Detection ---
    // Horizontal lines
    for (let y = 0; y < height; y++) {
        const firstPixelColor = getPixel(0, y);
        let similarCount = 1;
        for (let x = 1; x < width; x++) {
            if (colorDiff(firstPixelColor, getPixel(x, y)) < colorSimilarityTolerance) {
                similarCount++;
            }
        }
        if (similarCount / width >= lineDetectionThreshold) {
            issues.lines.push({ x: 0, y, w: width, h: 1, type: 'H' });
        }
    }
    // Vertical lines
    for (let x = 0; x < width; x++) {
        const firstPixelColor = getPixel(x, 0);
        let similarCount = 1;
        for (let y = 1; y < height; y++) {
            if (colorDiff(firstPixelColor, getPixel(x, y)) < colorSimilarityTolerance) {
                similarCount++;
            }
        }
        if (similarCount / height >= lineDetectionThreshold) {
            issues.lines.push({ x, y: 0, w: 1, h: height, type: 'V' });
        }
    }

    // --- 3. Crack/Blackout Area Detection ---
    const blockSize = 32;
    for (let by = 0; by < height; by += blockSize) {
        for (let bx = 0; bx < width; bx += blockSize) {
            let darkPixelCount = 0;
            const currentBlockW = Math.min(blockSize, width - bx);
            const currentBlockH = Math.min(blockSize, height - by);

            for (let y = by; y < by + currentBlockH; y++) {
                for (let x = bx; x < bx + currentBlockW; x++) {
                    const i = (y * width + x) * 4;
                    if ((data[i] + data[i + 1] + data[i + 2]) < crackDarknessValue) {
                        darkPixelCount++;
                    }
                }
            }
            const totalPixelsInBlock = currentBlockW * currentBlockH;
            if (totalPixelsInBlock > 0 && (darkPixelCount / totalPixelsInBlock) >= crackAreaThreshold) {
                issues.areas.push({ x: bx, y: by, w: currentBlockW, h: currentBlockH });
            }
        }
    }

    // --- 4. Draw Visualizations ---
    ctx.lineWidth = Math.max(1, Math.ceil(Math.min(width, height) / 500));
    const fontSize = Math.max(12, Math.ceil(Math.min(width, height) / 60));
    ctx.font = `bold ${fontSize}px Arial`;

    // Draw pixel issues
    ctx.strokeStyle = 'rgba(255, 0, 255, 0.9)'; // Magenta for pixels
    issues.pixels.forEach(p => {
        ctx.beginPath();
        const radius = Math.max(4, Math.ceil(fontSize / 3));
        ctx.arc(p.x + 0.5, p.y + 0.5, radius, 0, 2 * Math.PI);
        ctx.stroke();
    });

    // Draw line issues
    ctx.strokeStyle = 'rgba(255, 255, 0, 0.9)'; // Yellow for lines
    ctx.fillStyle = 'rgba(255, 255, 0, 0.3)';
    issues.lines.forEach(l => {
        ctx.fillRect(l.x, l.y, l.w, l.h);
        ctx.strokeRect(l.x, l.y, l.w, l.h);
    });

    // Draw area issues
    ctx.strokeStyle = 'rgba(255, 0, 0, 0.9)'; // Red for areas
    ctx.fillStyle = 'rgba(255, 0, 0, 0.4)';
    issues.areas.forEach(a => {
        ctx.fillRect(a.x, a.y, a.w, a.h);
        ctx.strokeRect(a.x, a.y, a.w, a.h);
    });

    // --- 5. Add Summary Text Box ---
    const summaryText = `Analysis: ${issues.pixels.length} pixel(s), ${issues.lines.length} line(s), ${issues.areas.length} damaged area(s) found.`;
    const textMetrics = ctx.measureText(summaryText);
    const textPadding = fontSize / 2;
    const boxHeight = fontSize + textPadding;
    const boxWidth = textMetrics.width + textPadding * 2;

    ctx.fillStyle = 'rgba(0, 0, 0, 0.75)';
    ctx.fillRect(0, height - boxHeight, boxWidth, boxHeight);
    ctx.fillStyle = 'white';
    ctx.fillText(summaryText, textPadding, height - textPadding / 2 - 2);

    return canvas;
}

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 Analysis for TV Damage Assessment tool analyzes images of television screens to detect common types of damage, including dead or stuck pixels, solid lines, and dark areas that may indicate cracks. Using configurable sensitivity parameters, users can upload an image of a TV screen, and the tool will visually highlight potential issues on the image, providing a quick overview of the screen’s condition. This tool is useful for technicians assessing repairs, consumers evaluating the condition of a used TV before purchase, or for warranty claims assessment.

Leave a Reply

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