为什么我的图片没有更新?

时间:2015-06-16 18:53:33

标签: javascript jquery

代码

var back1 = {r: 206, g: 77, b: 49}
var back2 = {r: 49, g: 142, b: 66}
var back3 = {r: 66, g: 138, b: 181}
var back4 = {r: 41, g: 81, b: 148}
var back5 = {r: 206, g: 178, b: 49}
var back6 = {r: 165, g: 93, b: 165}
var back7 = {r: 24, g: 32, b: 33}
var back8 = {r: 82, g: 44, b: 115}
var back9 = {r: 24, g: 109, b: 173}
var back10 = {r: 156, g: 40, b: 49}
var back11 = {r: 214, g: 199, b: 198}
var back12 = {r: 41, g: 36, b: 82}
var PATTERN = 1;

defaultImage = "res/img/clan-badge/Pattern_" + PATTERN + ".png";
defaultBackground = back1;

var image = new Image();
image.src = defaultImage;
image.onload = main;

function main(pattern, background) {
    background = typeof background !== 'undefined' ? background : defaultBackground;
    PATTERN = pattern;
    $('#image0').attr("src", defaultImage);
    // replace red with green
    recolorImage(image, 99, 101, 99, background.r, background.g, background.b);
}

function recolorImage(img, oldRed, oldGreen, oldBlue, newRed, newGreen, newBlue) {

    var c = document.createElement('canvas');
    var ctx = c.getContext("2d");
    var w = img.width;
    var h = img.height;

    c.width = w;
    c.height = h;

    // draw the image on the temporary canvas
    ctx.drawImage(img, 0, 0, w, h);

    // pull the entire image into an array of pixel data
    var imageData = ctx.getImageData(0, 0, w, h);

    // examine every pixel, 
    // change any old rgb to the new-rgb
    for (var i = 0; i < imageData.data.length; i += 4) {
        // is this pixel the old rgb?
        if (imageData.data[i] == oldRed && imageData.data[i + 1] == oldGreen && imageData.data[i + 2] == oldBlue) {
            // change to your new rgb
            imageData.data[i] = newRed;
            imageData.data[i + 1] = newGreen;
            imageData.data[i + 2] = newBlue;
        }
    }
    // put the altered data back on the canvas  
    ctx.putImageData(imageData, 0, 0);
    // put the re-colored image back on the image
    var img1 = document.getElementById("image0");
    img1.src = c.toDataURL('image/png');

}

问题

我的问题是当我运行main()函数时。它不会更新图像。它确实将PATTERN变量更新为我传入主参数的任何内容,但即使PATTERN更新,html /物理图像也不会改变。这是因为代码首先执行,因此无法更新代码吗?因为如果我刷新页面它会立即给我我想要的图像,但是当我重新加载页面时它会回到默认状态。

EXTRA

非常感谢代码改进。如果您还有其他问题,请随时告诉我您的问题可能是什么。我会尝试为您的问题提供最佳答案。

1 个答案:

答案 0 :(得分:3)

PATTERN确实已更新,但defaultImage没有更新,因为defaultImage = "res/img/clan-badge/Pattern_" + PATTERN + ".png";仅在更新PATTERN之前运行(main()内)

PATTERN = pattern; defaultImage = "res/image/clan-badge/Pattern_" + PATTERN + ".png";之后。

修改

以下是我建议的更新摘要:

var back = [
        {r: 206, g: 77, b: 49},
        {r: 49, g: 142, b: 66},
        {r: 66, g: 138, b: 181},
        {r: 41, g: 81, b: 148},
        {r: 206, g: 178, b: 49},
        {r: 165, g: 93, b: 165},
        {r: 24, g: 32, b: 33},
        {r: 82, g: 44, b: 115},
        {r: 24, g: 109, b: 173},
        {r: 156, g: 40, b: 49},
        {r: 214, g: 199, b: 198},
        {r: 41, g: 36, b: 82}
    ], // use back[0] through back[11] to reference these
    defaultImage = 'res/img/clan-badge/Pattern_1.png',
    defaultBackground = back[0];

function main(pattern, background) {
    var image = typeof pattern !== 'undefined' ? 'res/img/clan-badge/Pattern_' + pattern + '.png' : defaultImage,
        img = new Image();

    background = typeof background !== 'undefined' ? background : defaultBackground;

    img.src = image;
    img.onload = function () {
        // replace background color
        recolorImage(img, 99, 101, 99, background.r, background.g, background.b);
    };
}

function recolorImage(img, oldRed, oldGreen, oldBlue, newRed, newGreen, newBlue) {
    var c = document.createElement('canvas'),
        ctx = c.getContext('2d'),
        w = img.width,
        h = img.height;

    c.width = w;
    c.height = h;

    // draw the image on the temporary canvas
    ctx.drawImage(img, 0, 0, w, h);

    // pull the entire image into an array of pixel data
    var imageData = ctx.getImageData(0, 0, w, h);

    // examine every pixel, 
    // change any old rgb to the new-rgb
    for (var i = 0; i < imageData.data.length; i += 4) {
        // is this pixel the old rgb?
        if (imageData.data[i] == oldRed && imageData.data[i + 1] == oldGreen && imageData.data[i + 2] == oldBlue) {
            // change to your new rgb
            imageData.data[i] = newRed;
            imageData.data[i + 1] = newGreen;
            imageData.data[i + 2] = newBlue;
        }
    }
    // put the altered data back on the canvas  
    ctx.putImageData(imageData, 0, 0);
    // put the re-colored image back on the image
    $('#image0').attr('src', c.toDataURL('image/png'));
}

基本上问题是您没有更新Image对象的来源,只更新了PATTERNdefaultImage。我希望这会对你有所帮助。

<强>替代物

如果我可能会建议进一步更改,为什么不为每个所需的背景创建图像,这样您就不需要Canvas API来逐个像素地编辑它?也许像res/img/clan-badge/PATTERN/BACKGROUND/image.png之类的路径。

另一个替代方案是使每个徽章的背景部分透明(因为它们是PNG图像),并且在将图像加载到DOM之后,只需将<img>的背景颜色通过CSS设置为RGB来自back数组的三元组,再次避免使用Canvas API进行逐像素编辑,如下所示:

function main(pattern, background) {
    // assuming image is transparent where background will show through
    var image = typeof pattern !== 'undefined' ? 'res/img/clan-badge/Pattern_' + pattern + '.png' : defaultImage;

    background = typeof background !== 'undefined' ? background : defaultBackground;

    $('#image0')
        .attr('src', image)
        // set background through CSS
        .css('background-color', 'rgb(' + background.r + ',' + background.g + ',' + background.b + ')');
}