You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试jsfeat.js时仅显示黑色画布,求排查问题原因

使用jsfeat.js处理图像时Canvas输出全黑的问题

我尝试用jsfeat.js做图像处理,但运行代码后Canvas只显示黑色。以下是我的实现代码,请问哪里操作出错了?

<html>
<head>
    <style>
        img {
            border: solid 1px red;
            width: 20vw;
        }

        canvas {
            border: solid 1px blue;
            width: 80vw;
        }
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jsfeat/0.0.8/jsfeat-min.js"></script>
</head>
<body>
<img src='http://localhost/.../images/test-image.jpg'>

<script>
    function processImage(canvas, img, radius, low_threshold, high_threshold) {
        let w=img.naturalWidth;
        let h=img.naturalHeight;
        canvas.width = w;
        canvas.height = h;
        const ctx = canvas.getContext('2d');

        let img_u8 = new jsfeat.matrix_t(w, h, jsfeat.U8_t | jsfeat.C1_t);
        var imageData = ctx.getImageData(0, 0, w, h);

        jsfeat.imgproc.grayscale(imageData.data, w, h, img_u8);

        // render result back to canvas
        var data_u32 = new Uint32Array(imageData.data.buffer);
        var alpha = (0xff << 24);
        var i = img_u8.cols*img_u8.rows, pix = 0;
        while(--i >= 0) {
            pix = img_u8.data[i];
            data_u32[i] = alpha | (pix << 16) | (pix << 8) | pix;
        }
        ctx.putImageData(imageData, 0, 0);

    }
    let canvas = document.createElement('canvas');
    document.body.appendChild(canvas);
    const img = document.querySelector('img');

    let radius=3;
    let low_threshold=127;
    let high_threshold=127;

    if (img.complete) {
        console.log('img already loaded');
        processImage(canvas, img,radius, low_threshold, high_threshold);
    }
    else {
        img.onload = function () {
            console.log('img loaded');
            processImage(canvas, img,radius, low_threshold, high_threshold);
        };

        img.onerror = function () {
            console.error('Failed to load the image.');
        };
    }
</script>
</body>
</html>

问题原因及修复

核心错误是没有先将图像绘制到Canvas就调用了getImageData:

Canvas初始化后是空的,直接调用getImageData获取到的是全黑(像素值为0)的初始数据,后续转灰度处理自然还是全黑。

修复步骤:

在processImage函数中,获取imageData之前,添加一行代码将图片绘制到Canvas:

const ctx = canvas.getContext('2d');
// 新增这行:把图片绘制到Canvas
ctx.drawImage(img, 0, 0);
// 之后再获取图像数据
var imageData = ctx.getImageData(0, 0, w, h);

修正后的完整processImage函数:

function processImage(canvas, img, radius, low_threshold, high_threshold) {
    let w=img.naturalWidth;
    let h=img.naturalHeight;
    canvas.width = w;
    canvas.height = h;
    const ctx = canvas.getContext('2d');

    // 先把图片绘制到Canvas
    ctx.drawImage(img, 0, 0);

    let img_u8 = new jsfeat.matrix_t(w, h, jsfeat.U8_t | jsfeat.C1_t);
    var imageData = ctx.getImageData(0, 0, w, h);

    jsfeat.imgproc.grayscale(imageData.data, w, h, img_u8);

    // render result back to canvas
    var data_u32 = new Uint32Array(imageData.data.buffer);
    var alpha = (0xff << 24);
    var i = img_u8.cols*img_u8.rows, pix = 0;
    while(--i >= 0) {
        pix = img_u8.data[i];
        data_u32[i] = alpha | (pix << 16) | (pix << 8) | pix;
    }
    ctx.putImageData(imageData, 0, 0);
}

这样就能正确获取到图片的像素数据,处理后Canvas会显示灰度图像。

内容的提问来源于stack exchange,提问作者abe1432181

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:08:17