How to flip images horizontally with HTML5

前端 未结 7 1147
暖寄归人
暖寄归人 2020-11-28 07:14

In IE, I can use:


to implement an image flip horizontally.

相关标签:
7条回答
  • 2020-11-28 07:52

    I came across this page, and no-one had quite written a function to do what I wanted, so here's mine. It draws scaled, rotated, and flipped images (I used this for rending DOM elements to canvas that have these such transforms applied).

    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();
    }
    
    0 讨论(0)
  • 2020-11-28 07:57

    One option is to horizontally flip the pixels of images stored in ImageData objects directly, e.g.

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

    0 讨论(0)
  • 2020-11-28 08:01

    I like Eschers function above. I have made it a little neater and better. I have added flop (vertically) besides flip. Also a possibility to draw/rotate around the center of the image instead of top left. Finally, the function does not require all arguments. img, x and y are required but the rest are not.

    If you were using something like context.drawImage(...), you can now just use drawImage(...) and add the rotate/flip/flop functionality explained here:

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

    Examples:

    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 :-)
    
    0 讨论(0)
  • 2020-11-28 08:10
    canvas = document.createElement('canvas');
    canvasContext = canvas.getContext('2d');
    
    canvasContext.translate(width, 0);
    canvasContext.scale(-1, 1);
    this.canvasContext.drawImage(image, 0, 0);
    

    Here's a snippet from a sprite object being used for testing and it produces the results you seem to expect.

    Here's another site with more details. http://andrew.hedges.name/widgets/dev/

    0 讨论(0)
  • 2020-11-28 08:12

    Mirror an image or rendering using the canvas.

    Note. This can be done via CSS as well.


    Mirroring

    Here is a simple utility function that will mirror an image horizontally, vertically or both.

    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
    }
    

    Usage

    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
    

    Drawable image.

    Many times you will want to draw on images. I like to call them drawable images. To make an image drawable you convert it to a canvas

    To convert an image to canvas.

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

    Putting it all together

     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
     
    

    More mirrors

    If you wish to be able to mirror along an arbitrary line see the answer Mirror along line

    0 讨论(0)
  • 2020-11-28 08:14

    You don't need HTML5, it can be done with CSS same as in IE:

    -moz-transform: scale(-1, 1);
    -webkit-transform: scale(-1, 1);
    -o-transform: scale(-1, 1);
    transform: scale(-1, 1);
    filter: FlipH;
    
    0 讨论(0)
提交回复
热议问题