16

我已经看到了一些关于如何调整要在 IMG 标记中使用的图像大小的技巧,但我想在 Javascript 中有一个图像变量,调整它的大小,然后在 context.createPattern(image, "重复”)。我还没有找到任何关于如何做到这一点的提示。

您可以在http://karllarsson.batcave.net/moon.html找到一个功能演示, 其中包含我想要做的图像。

Loktar 的解决方案看起来不错。我还没有时间修复正确的方面,但现在我知道该怎么做了。再一次感谢你。这是一个工作演示http://karllarsson.batcave.net/moon2.html

这是我不想工作的两条线。

image.width = 边 * 2;
image.height = 边 * 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);                                                 
    }
}
4

3 回答 3

23

您可以做的是制作一个临时画布,并将图像以您需要的尺寸复制到其中,然后将该临时画布用作图案而不是图像本身。

现场演示

首先创建画布

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

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

现在将图像绘制到它,使您需要的缩放大小

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

现在使用您刚刚创建的画布作为图案

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

完整代码

编辑创建了一个更通用的可重用示例

 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);
}
于 2012-12-19T22:32:54.067 回答
1

还有另一种方法,对我很有用:

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;

基本上与将变换矩阵设置为此相同(以下内容)(但注意!模式 setTransform 方法等待一个 SVGMatrix。这在 Chrome 中也对我有用(但 TypeScript 抱怨当然):

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
});

请记住,您可能还需要在绘制图案之前翻译您的画布,否则它无法从您希望它开始的位置开始。

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);
于 2019-06-09T08:44:15.007 回答
0

这是使用范围按钮调整图像上图案大小的另一种方法。

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.stack.imgur.com/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 标记

<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>

和功能

function resizePattern() {
    go();
}

您可以对其进行调整以查看不同的结果。

于 2021-09-02T14:47:59.177 回答