最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Resize an imagewith javascript for use inside a canvas createPattern - Stack Overflow

programmeradmin1浏览0评论

I've seen a few tricks on how you resize an image you want to use inside an IMG-tag but I want to have an image variable inside a Javascript, resize it and then use the image inside a context.createPattern(image, "repeat"). I have not found any hint on how to do that.

You can find a functional demo at .html with images on what I want to do.

The solution from Loktar looks good. I haven't had the time yet to fix the correct aspect but now I know how to do it. Thank you once again. Here is an working demo .html

This is the two lines I don't get to work as I want them too.

image.width = side * 2;
image.height = side * 2;

function drawShape() {
    try {
        var canvas = document.getElementById('tutorial');                 
        var image = new Image();                                          
        image.src = "/jjj.jpg";                         
        image.width = side * 2;                                           
        image.height = side * 2;                                          

        if (canvas.getContext){
            var ctx = canvas.getContext('2d');                            
            ctx.clearRect(0, 0, canvas.width, canvas.height);             
            ctx.fillStyle = ctx.createPattern(image, "repeat");           
            ctx.beginPath();                                              
            var centerX = canvas.width / 2 - side / 2;                    
            var centerY = canvas.height / 2 - side / 2;                   
            ctx.rect(centerX, centerY, side, side);                       
            ctx.fill();                                                   
        } else {
            alert('You need Safari or Firefox 1.5+ to see this demo.');   
        }
    } catch (err) {
        console.log(err);                                                 
    }
}

I've seen a few tricks on how you resize an image you want to use inside an IMG-tag but I want to have an image variable inside a Javascript, resize it and then use the image inside a context.createPattern(image, "repeat"). I have not found any hint on how to do that.

You can find a functional demo at http://karllarsson.batcave.net/moon.html with images on what I want to do.

The solution from Loktar looks good. I haven't had the time yet to fix the correct aspect but now I know how to do it. Thank you once again. Here is an working demo http://karllarsson.batcave.net/moon2.html

This is the two lines I don't get to work as I want them too.

image.width = side * 2;
image.height = side * 2;

function drawShape() {
    try {
        var canvas = document.getElementById('tutorial');                 
        var image = new Image();                                          
        image.src = "http://xxx.yyy.zzz/jjj.jpg";                         
        image.width = side * 2;                                           
        image.height = side * 2;                                          

        if (canvas.getContext){
            var ctx = canvas.getContext('2d');                            
            ctx.clearRect(0, 0, canvas.width, canvas.height);             
            ctx.fillStyle = ctx.createPattern(image, "repeat");           
            ctx.beginPath();                                              
            var centerX = canvas.width / 2 - side / 2;                    
            var centerY = canvas.height / 2 - side / 2;                   
            ctx.rect(centerX, centerY, side, side);                       
            ctx.fill();                                                   
        } else {
            alert('You need Safari or Firefox 1.5+ to see this demo.');   
        }
    } catch (err) {
        console.log(err);                                                 
    }
}
Share Improve this question edited Dec 20, 2012 at 16:16 user1916806 asked Dec 19, 2012 at 20:23 user1916806user1916806 1711 silver badge5 bronze badges 2
  • What errors are you receiving? What else have you tried? – JSuar Commented Dec 19, 2012 at 20:43
  • The image does not resize, see demo. No actual errors. I have tried a few other things I have found here and there but none of them have been working. I don't have a list with what I have tried. – user1916806 Commented Dec 19, 2012 at 21:22
Add a comment  | 

3 Answers 3

Reset to default 23

What you can do is make a temporary canvas, and copy the image to it with the dimensions you require, and then use that temporary canvas as the pattern rather than the image itself.

Live Demo

First create the canvas

          var tempCanvas = document.createElement("canvas"),
              tCtx = tempCanvas.getContext("2d");

          tempCanvas.width = side*2;
          tempCanvas.height = side*2;

Now draw the image to it, making the the scaled size you require

          tCtx.drawImage(image,0,0,image.width,image.height,0,0,side*2,side*2);

And now use the canvas you just created as the pattern

          ctx.fillStyle = ctx.createPattern(tempCanvas, "repeat");

Full code

edit created a more generic reusable example

 function drawPattern(img, size) {
     var canvas = document.getElementById('canvas');

     canvas.height = 500;
     canvas.width = 500;

     var tempCanvas = document.createElement("canvas"),
         tCtx = tempCanvas.getContext("2d");

     tempCanvas.width = size;
     tempCanvas.height = size;
     tCtx.drawImage(img, 0, 0, img.width, img.height, 0, 0, size, size);

     // use getContext to use the canvas for drawing
     var ctx = canvas.getContext('2d');
     ctx.clearRect(0, 0, canvas.width, canvas.height);
     ctx.fillStyle = ctx.createPattern(tempCanvas, 'repeat');

     ctx.beginPath();
     ctx.rect(0,0,canvas.width,canvas.height);
     ctx.fill();

}

var img = new Image();
img.src = "http://static6.depositphotos.com/1070439/567/v/450/dep_5679549-Moon-Surface-seamless.jpg";
img.onload = function(){
    drawPattern(this, 100);
}

There is another way, which worked great for me:

const ctx: CanvasRenderingContext2D;
const patternAsBase64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpGRjIyRTA3RDgyNkUxMUU5ODQ1QUM2QjE5RUMzRTMwRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGRjIyRTA3RTgyNkUxMUU5ODQ1QUM2QjE5RUMzRTMwRCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkZGMjJFMDdCODI2RTExRTk4NDVBQzZCMTlFQzNFMzBEIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkZGMjJFMDdDODI2RTExRTk4NDVBQzZCMTlFQzNFMzBEIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+y2y13AAAAV1JREFUeNqc0kFLAkEUB/B9b1ZR1m4FQZeocx2MYI3CxC8QmVBfJAjqVLQQfY/MFI+dREpQIeqQxwgiCrq72661M9Nb0ZKo3dU5zOU//Hj/3Qep04YUn04Ludxq7mdflYCzfFKbprdnLKatc9u8Z1zZbBxkHwc58q79gpGYLgBKqaPqTBB4s5t5Ewx2XNu8YvHEImeysnJYnf8GoyCz/MO+ZXFN56iUw6JSxW333SJ0YoEzpbJq1Oe8DLxLN2qzQoqSGkss8a41Un1wZUGNa2mq346A3IBB6KGSUOahdqeFEsZAO20YDnXjktDomKgoUMM0/A6HJ3UJZSNOCn+FPVSIMv3FpOuYTSaUfGj0v/AH1ZLcsZoYEgW/sF+/TPUJNUOh6Be29jJPAJijlbgjNEV7ehG0p6CEOIP62K/v900xXyyyILA3KWJO2FbgpPj8MHm+dnw9FRp1/Ot/CTAAd/XmF3ta0fUAAAAASUVORK5CYII=';
const imagePattern = new Image();
imagePattern.onload = () => {
    const pattern: CanvasPattern = ctx.createPattern(imagePattern, 'repeat-y');
    const svgMatrix: SVGMatrix = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix();

    svgMatrix.scale(0.5);
    pattern.setTransform(svgMatrix);
}
imagePattern.src = patternAsBase64;

Basically the same as setting the transform matrix to this (the following down under) (But attention! patterns setTransform method awaits a SVGMatrix. This did still work for me, too in Chrome (But TypeScript complained of course):

pattern.setTransform({
    a: 0.5, // Horizontal scaling. A value of 1 results in no scaling.
    b: 0,   // Vertical skewing.
    c: 0,   // Horizontal skewing.
    d: 0.5, // Vertical scaling. A value of 1 results in no scaling.
    e: 0,   // Horizontal translation (moving).
    f: 0    // Vertical translation (moving).
    // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/transform
});

Keep in mind, that you also maybe need to translate your canvas before drawing the pattern, otherwise it could not start where you want it to start to.

const offset_x: number = positionXOfElement;
const offset_y: number = positionYOfElement;

// offset
ctx.translate(offset_x, offset_y);

// draw
ctx.fillStyle = pattern;
roundRect.fill();
//ctx.fillRect(0, 0, 300, 300);

// undo offset
ctx.translate(-offset_x, -offset_y);

Here is another way to resize pattern on image with range button.

var img1 = new Image, img2 = new Image, cnt = 2,
    canvas = document.getElementById("canvas"),
    canvas_original = document.getElementById("canvas_original"),
    ctx_original = canvas_original.getContext("2d"),
    ctx = canvas.getContext("2d");

img1.onload = img2.onload = function() {if (!--cnt) go()};

img1.src = "https://www.itailor.co.uk/images/product/shirt/it1823-1.png";   // shirt

img2.src = "https://i.sstatic.net/tkBVh.png";   // pattern

function go(source = null) {
    canvas.width = document.getElementById("first").clientWidth;
    canvas.height = window.innerHeight / 2;

    canvas_original.width = document.getElementById("second").clientWidth;
    canvas_original.height = window.innerHeight / 2;

    var oc = document.createElement('canvas'), octx = oc.getContext('2d');

    var cur = {
        width: Math.floor(img1.width * 0.5),
        height: Math.floor(img1.height * 0.5)
    }

    oc.width = cur.width;
    oc.height = cur.height;

    octx.drawImage(img1, 0, 0, cur.width, cur.height);

    while (cur.width * 0.5 > document.getElementById("first").clientWidth) {
        cur = {
            width: Math.floor(cur.width * 0.5),
            height: Math.floor(cur.height * 0.5)
        };
        octx.drawImage(oc, 0, 0, cur.width * 2, cur.height * 2, 0, 0, cur.width, cur.height);
    }

    ctx_original.drawImage(oc, 0, 0, cur.width, cur.height, 0, 0, canvas.width, canvas.height);

    //****//
    var rate = $('#rate').val();

    var tempCanvas = document.createElement("canvas"),
        tCtx = tempCanvas.getContext("2d");

    tempCanvas.width = canvas.width / 4 * rate;

    tempCanvas.height = canvas.height / 4 * rate;

    tCtx.drawImage(img2, 0, 0, img2.width, img2.height, 0, 0, tempCanvas.width, tempCanvas.height);
    //****//

    if (source !== null) {
        ctx.fillStyle = ctx.createPattern(tempCanvas, "repeat");
    }
    else {
        ctx.fillStyle = ctx.createPattern(tempCanvas, "repeat");
    }

    ctx.fillRect(0, 0, canvas.width, canvas.height);

    ctx.globalCompositeOperation = "multiply";

    ctx.drawImage(oc, 0, 0, cur.width, cur.height, 0, 0, canvas.width, canvas.height);

    ctx.globalCompositeOperation = "destination-in";

    ctx.drawImage(oc, 0, 0, cur.width, cur.height, 0, 0, canvas.width, canvas.height);
}

HTML Markup

<div class="container" style="width: 100%; padding-right: 0 !important; padding-left: 0 !important;">
    <div id="clothesDiv" class="col-lg-2" style="max-height: 100vh; overflow-y: auto;">
    </div>
    <div class="col-lg-10">
        <div class="row" style="margin-right: 0 !important; margin-left: 0 !important; border: 0.5px solid black;">
            <div id="first" class="col-lg-6" style="padding-right: 0 !important; padding-left: 0 !important;">
                <canvas id="canvas_original"></canvas>
            </div>
            <div id="second" class="col-lg-6" style="padding-right: 0 !important; padding-left: 0 !important;">
                <canvas id="canvas"></canvas>
            </div>
        </div>
        <div class="row" style="margin-right: 0 !important; margin-left: 0 !important;">
            <div class="col-lg-offset-3 col-lg-6">
                <p class="text-center">Desen Ölçeklendirme</p>
                <input id="rate" type="range" min="1" max="4" value="4" onchange="resizePattern()"/>
            </div>
        </div>

And function

function resizePattern() {
    go();
}

You can tweak it to see different results.

发布评论

评论列表(0)

  1. 暂无评论