【问题标题】:How to flip images horizontally with HTML5如何使用 HTML5 水平翻转图像
【发布时间】:2010-06-27 22:18:19
【问题描述】:

在 IE 中,我可以使用:

<img src="http://example.com/image.png" style="filter:FlipH">

实现图像水平翻转。

有没有办法在 HTML5 中水平翻转? (也许通过使用画布?)

谢谢大家:)

【问题讨论】:

    标签: html canvas


    【解决方案1】:
    canvas = document.createElement('canvas');
    canvasContext = canvas.getContext('2d');
    
    canvasContext.translate(width, 0);
    canvasContext.scale(-1, 1);
    canvasContext.drawImage(image, 0, 0);
    

    这是一个用于测试的 sprite 对象的 sn-p,它产生了您似乎期望的结果。

    这是另一个提供更多详细信息的网站。 http://andrew.hedges.name/widgets/dev/

    【讨论】:

    • 我们不使用css有什么原因吗? transform: scaleX(-1); 有保存/发布图片之类的问题吗?
    • 如果我需要在同一个画布上绘制多个图像但只有水平翻转的图像怎么办
    【解决方案2】:

    您不需要 HTML5,可以使用与 IE 中相同的 CSS 来完成:

    -moz-transform: scale(-1, 1);
    -webkit-transform: scale(-1, 1);
    -o-transform: scale(-1, 1);
    transform: scale(-1, 1);
    filter: FlipH;
    

    【讨论】:

    • 没有这个我怎么活?!太棒了!
    • 这是迄今为止最酷的解决方案;再次感谢 CSS 让我们的生活更轻松...
    【解决方案3】:

    我喜欢上面的 Escher 函数。我已经使它更整洁更好了。除了翻转之外,我还添加了 flop(垂直)。还可以围绕图像的中心绘制/旋转,而不是左上角。最后,该函数不需要所有参数。 img、x 和 y 是必需的,但其余的都不是。

    如果您使用的是 context.drawImage(...) 之类的东西,您现在只需使用 drawImage(...) 并添加旋转/翻转/翻牌功能在这里解释:

    function drawImage(img, x, y, width, height, deg, flip, flop, center) {
    
    context.save();
    
    if(typeof width === "undefined") width = img.width;
    if(typeof height === "undefined") height = img.height;
    if(typeof center === "undefined") center = false;
    
    // Set rotation point to center of image, instead of top/left
    if(center) {
        x -= width/2;
        y -= height/2;
    }
    
    // Set the origin to the center of the image
    context.translate(x + width/2, y + height/2);
    
    // Rotate the canvas around the origin
    var rad = 2 * Math.PI - deg * Math.PI / 180;    
    context.rotate(rad);
    
    // Flip/flop the canvas
    if(flip) flipScale = -1; else flipScale = 1;
    if(flop) flopScale = -1; else flopScale = 1;
    context.scale(flipScale, flopScale);
    
    // Draw the image    
    context.drawImage(img, -width/2, -height/2, width, height);
    
    context.restore();
    }
    

    例子:

    var myCanvas = document.getElementById("myCanvas");
    var context = myCanvas.getContext("2d"); // i use context instead of ctx
    
    var img = document.getElementById("myImage"); // your img reference here!
    
    drawImage(img, 100, 100); // just draw it 
    drawImage(img, 100, 100, 200, 50); // draw it with width/height specified
    drawImage(img, 100, 100, 200, 50, 45); // draw it at 45 degrees
    drawImage(img, 100, 100, 200, 50, 0, true); // draw it flipped
    drawImage(img, 100, 100, 200, 50, 0, false, true); // draw it flopped
    drawImage(img, 100, 100, 200, 50, 0, true, true); // draw it flipflopped
    drawImage(img, 100, 100, 200, 50, 45, true, true, true); // draw it flipflopped and 45 degrees rotated around the center of the image :-)
    

    【讨论】:

    • 我喜欢这个想法,我对其进行了一些改进,以便我可以将它与精灵表和某些位置一起使用
    【解决方案4】:

    一种选择是直接水平翻转存储在 ImageData 对象中的图像像素,例如

    function flip_image (canvas) {
       	var context   = canvas.getContext ('2d') ;
       	var imageData = context.getImageData (0, 0, canvas.width, canvas.height) ;
       	var imageFlip = new ImageData (canvas.width, canvas.height) ;
       	var Npel      = imageData.data.length / 4 ;
    
       	for ( var kPel = 0 ; kPel < Npel ; kPel++ ) {
       	   	var kFlip      = flip_index (kPel, canvas.width, canvas.height) ;
       	   	var offset     = 4 * kPel ;
       	   	var offsetFlip = 4 * kFlip ;
       	   	imageFlip.data[offsetFlip + 0] = imageData.data[offset + 0] ;
       	   	imageFlip.data[offsetFlip + 1] = imageData.data[offset + 1] ;
       	   	imageFlip.data[offsetFlip + 2] = imageData.data[offset + 2] ;
       	   	imageFlip.data[offsetFlip + 3] = imageData.data[offset + 3] ;
       	}
    
       	var canvasFlip = document.createElement('canvas') ;
       	canvasFlip.setAttribute('width', width) ;
       	canvasFlip.setAttribute('height', height) ;
    
       	canvasFlip.getContext('2d').putImageData(imageFlip, 0, 0) ;
       	return canvasFlip ;
    }
    
    function flip_index (kPel, width, height) {
       	var i     = Math.floor (kPel / width) ;
       	var j     = kPel % width ;
       	var jFlip = width - j - 1 ;
       	var kFlip = i * width + jFlip ;
       	return kFlip ;
    }

    【讨论】:

      【解决方案5】:

      使用画布镜像图像或渲染。

      注意。这也可以通过 CSS 完成。


      镜像

      这是一个简单的实用功能,可以水平、垂直或同时镜像图像。

      function mirrorImage(ctx, image, x = 0, y = 0, horizontal = false, vertical = false){
          ctx.save();  // save the current canvas state
          ctx.setTransform(
              horizontal ? -1 : 1, 0, // set the direction of x axis
              0, vertical ? -1 : 1,   // set the direction of y axis
              x + (horizontal ? image.width : 0), // set the x origin
              y + (vertical ? image.height : 0)   // set the y origin
          );
          ctx.drawImage(image,0,0);
          ctx.restore(); // restore the state as it was when this function was called
      }
      

      用法

      mirrorImage(ctx, image, 0, 0, true, false); // horizontal mirror
      mirrorImage(ctx, image, 0, 0, false, true); // vertical mirror
      mirrorImage(ctx, image, 0, 0, true, true);  // horizontal and vertical mirror
      

      可绘制的图像。

      很多时候你会想在图像上画画。我喜欢称它们为可绘制图像。要使图像可绘制,请将其转换为画布

      将图像转换为画布。

      function makeImageDrawable(image){
          if(image.complete){ // ensure the image has loaded
              var dImage = document.createElement("canvas"); // create a drawable image
              dImage.width = image.naturalWidth;      // set the resolution
              dImage.height = image.naturalHeight;
              dImage.style.width = image.style.width; // set the display size
              dImage.style.height = image.style.height; 
              dImage.ctx = dImage.getContext("2d");   // get drawing API
                                                      // and add to image
                                                      // for possible later use
              dImage.ctx.drawImage(image,0,0);
              return dImage;
          }
          throw new ReferenceError("Image is not complete.");
       }
      

      把它们放在一起

       var dImage = makeImageDrawable(image);  // convert DOM img to canvas
       mirrorImage(dImage.ctx, dImage, 0, 0, false, true); // vertical flip
       image.replaceWith(dImage);  // replace the DOM image with the flipped image
       
      

      更多镜子

      如果您希望能够沿任意线镜像,请参阅答案Mirror along line

      【讨论】:

        【解决方案6】:

        我遇到了这个页面,没有人写过一个函数来做我想做的事,所以这是我的。它绘制缩放、旋转和翻转的图像(我用它来将 DOM 元素渲染到应用了这些变换的画布上)。

        var myCanvas = document.getElementById("myCanvas");
        var ctx = myCanvas.getContext("2d");
        var img = document.getElementById("myimage.jpg"); //or whatever
        var deg = 13; //13 degrees rotation, for example
        var flip = "true";
        
        function drawImage(img, x, y, width, height, deg, flip){
            //save current context before applying transformations
            ctx.save();
            //convert degrees to radians
            if(flip == "true"){ 
                var rad = deg * Math.PI / 180;
            }else{
                var rad = 2*Math.PI - deg * Math.PI / 180;
            }
            //set the origin to the center of the image
            ctx.translate(x + width/2, y + height/2);
            //rotate the canvas around the origin
            ctx.rotate(rad);
            if(flip == "true"){
                //flip the canvas
                ctx.scale(-1,1);
            }
            //draw the image    
            ctx.drawImage(img, -width/2, -height/2, width, height);
            //restore the canvas
            ctx.restore();
        }
        

        【讨论】:

          【解决方案7】:

          对于任何偶然发现这一点的人。 如果您想做更复杂的绘图,其他基于比例的答案并不都有效。 “复杂”是指事物更加动态的情况,例如游戏。

          问题是位置也被翻转了。所以如果你想在画布的左上角画一个小图,然后水平翻转,它会重新定位到右上角。

          解决方法是平移到要绘制图像的中心,然后缩放,然后再平移回来。像这样:

          if (flipped) {
            ctx.translate(x + width/2, y + width/2);
            ctx.scale(-1, 1);
            ctx.translate(-(x + width/2), -(y + width/2));
          }
          ctx.drawImage(img, x, y, width, height);
          

          这里x和y是你要绘制图片的位置,width和height是你要绘制图片的宽度和高度。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-01-05
            • 2022-01-22
            • 2018-01-17
            • 1970-01-01
            • 2019-11-26
            相关资源
            最近更新 更多