How to horizontally flip an image
Asked Answered
N

5

9

How can i draw only two images with reversing I don't know how to reverse. Pls help.

    var canvas = document.createElement('canvas');
    canvas.width = 16 * scale;
    canvas.height = 32 * scale;
    //we assign the same classname the image has, for CSS purposes
    canvas.setAttribute('class', skinImage.getAttribute('class'));
    canvas.setAttribute('title', skinImage.getAttribute('title'));
    var context = canvas.getContext("2d"),
    s = scale;
    context.imageSmoothingEnabled=!1,
    context.mozImageSmoothingEnabled=!1,
    context.oImageSmoothingEnabled=!1,
    CanvasRenderingContext2D.webkitImageSmoothingEnabled=!1,
    context.clearRect(0,0,canvas.width,canvas.height);

    //back draw the head
    context.drawImage(skinImage, 24,  8,  8, 8,  4*s,  0*s,  8*s, 8*s);
    //back draw the body
    context.drawImage(skinImage, 32, 20, 8, 12, 4*s,  8*s,  8*s, 12*s);
    //back draw the right leg
    context.drawImage(skinImage, 52, 20, 4, 12, 12*s, 8*s,  4*s, 12*s);
    //back draw the right arm
    context.drawImage(skinImage, 12, 20, 4, 12, 8*s,  20*s, 4*s, 12*s);

    //back draw the left arm
    context.drawImage(skinImage, 12, 20, 4, 12, 4*s,  20*s, 4*s, 12*s);
    context.drawImage(skinImage, 52, 20, 4, 12, 0*s,  8*s,  4*s, 12*s);
Naquin answered 13/3, 2016 at 17:35 Comment(1)
why don't we use css? transform: scaleX(-1);Denunciation
B
10

First, to remove your 2 unwanted image, just clear the canvas and redraw the desired images. You can clear the canvas using context.clearRect(0,0,canvas.width,canvas.height).

Flip image(s) horizontally

enter image description here

How to horizontally flip an image:

  1. Move (translate) the canvas origin to your desired X-coordinate plus the image width: context.translate(x + img.width, y); Adding the img.width is necessary because we are grabbing the left edge of the image and flipping it leftward. Without adding img.width, the img would be drawn leftward of the desired x-coordinate.

  2. Flip horizontally using context.scale(-1, 1);

  3. Draw the image: context.drawImage(img, 0, 0);

  4. Clean up by resetting transformations to their default values: context.setTransform(1, 0, 0, 1, 0, 0);

Annotated code and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sillouette2.png";
function start(){

    ctx.fillText('original',10,30);
    ctx.drawImage(img,10,30);

    ctx.fillText('flipped',150,30);
    flipHorizontally(img,150,30);

}

function flipHorizontally(img,x,y){
    // move to x + img's width
    ctx.translate(x+img.width,y);

    // scaleX by -1; this "trick" flips horizontally
    ctx.scale(-1,1);
    
    // draw the img
    // no need for x,y since we've already translated
    ctx.drawImage(img,0,0);
    
    // always clean up -- reset transformations to default
    ctx.setTransform(1,0,0,1,0,0);
}
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

[Addition: flipping a sprite from a spritesheet]

To flip a sprite that's contained in a spritesheet you can use the cropping form of drawImage. The cropping drawImage will crop the desired sprite from the spritesheet by specifiying the sprite's spriteX, spriteY, spriteWidth & spriteHeight. The same cropping drawImage will also draw the cropped sub-image onto the canvas by specifying the desire canvas canvasX, canvasY, spriteWidth & spriteHeight.

Here is code showing how to flip a sprite from a spritesheet

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/cars.jpg";
function start(){

  var spriteX=92;
  var spriteY=63;
  var spriteW=80;
  var spriteH=40;

  ctx.fillText('original',10,30);
  ctx.drawImage(img,spriteX,spriteY,spriteW,spriteH,10,30,spriteW,spriteH);

  ctx.fillText('flipped',150,30);
  flipSpriteHorizontally(img,150,30, spriteX,spriteY,spriteW,spriteH);

}

function flipSpriteHorizontally(img,x,y,spriteX,spriteY,spriteW,spriteH){
  // move to x + img's width
  // adding img.width is necessary because we're flipping from
  //     the right side of the img so after flipping it's still
  //     at [x,y]
  ctx.translate(x+spriteW,y);

  // scaleX by -1; this "trick" flips horizontally
  ctx.scale(-1,1);

  // draw the img
  // no need for x,y since we've already translated
  ctx.drawImage(img,
                spriteX,spriteY,spriteW,spriteH,0,0,spriteW,spriteH
               );

  // always clean up -- reset transformations to default
  ctx.setTransform(1,0,0,1,0,0);
}
#canvas{border:1px solid red; margin:0 auto; }
<h4>Drawing & horizontally flipping a sprite</h4>
<canvas id="canvas" width=300 height=100></canvas>
<h4>Spritesheet:</h4>
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/cars.jpg'>
Beutler answered 13/3, 2016 at 18:12 Comment(12)
it hides my images what should i do ?Naquin
Your question is unclear. Please take time to make your question more clear using the edit button under your question. ;-) I (might) understand from your previous question that you are drawing many images and you want to remove 2 of them. The typical method is to clear the canvas completely (context.clearRect(0,0,canvas.width,canvas.height) and then redraw only those images that you still want to appear.Beutler
oh sorry im not trying to remove 2 of them i have 6 images in one canvas and i want to reverse(mirror) 2 of them im tried scale and set transform but both of them hiding my 2 imagesNaquin
im sorry for my bad english :(Naquin
@TrkeRap. It's ok :-) -- We just need more information. Are you trying to flip the image horizontally? Meaning if a face image starts out looking right then you want to redraw that same face looking left? Or something else?Beutler
Yes exactly i want thatNaquin
@TrkeRap I've changed my answer to show how to remove your 2 unwanted images and how to horizontally flip any image.Beutler
its worked but it shows all of image that i draw but i want only one area in the image ex(from12,to20) what should i do ?Naquin
if i use translate it flips all the image i tried without translate but it becomes hiddenNaquin
@TrkeRap: To draw just 1 sprite from a spritesheet you can use the cropping form of drawImage to display just the desired sprite. I've added a code and demo showing how to do it. Good luck with your project!Beutler
oh its work but how i will set the canvas destination where the image will drawn in canvas ?Naquin
oh i fixed it tank you again for your helpNaquin
N
5

Mirror an image

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

// arguments
// ctx : the context on which to draw the mirrored image
// image : the image to mirror
// x,y : the top left of the rendered image
// horizontal : boolean if true mirror along X
// vertical : boolean if true mirror along y
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

More mirrors

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

Noenoel answered 17/3, 2017 at 11:41 Comment(1)
Amazing! Thanks! I was looking for this! :)Gastight
R
0

To mirror image you can use setTransform with negative scale.

context.setTransform(-1, 0, 0, 1, 0, 0);    //Now all images will be horizontally mirrored
context.drawImage(<myimage>, srcx, srcy, srcw, srch, dstx, dsty, dstw, dsth);

Don't forget to restore transform when you finished.

context.setTransform(1, 0, 0, 1, 0, 0);
Redivivus answered 13/3, 2016 at 17:46 Comment(1)
Read this: #8168717Redivivus
B
0
function mirrorImage(image, src_x, src_y, img_width, img_height, x, y){

   // 1. MIRROR THE CONTEXT
   context.scale(-1, 1);

   // 2. DRAW IN CANVAS USING (-X - img_width)
   context.drawImage(image, src_x, src_y, img_width, img_height, - 
   x - img_width, y, img_width, img_height);

   // 3. RETURN CONTEXT TO ORIGINAL STATE (AFTER DRAWING)
   context.scale(-1, 1);

}
Benedictine answered 7/8, 2022 at 10:42 Comment(0)
L
0

Either use a transformation matrix:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform

ctx.setTransform(
  -1, 0,
   0, 1,
   canvasWidth,
   0
);

Or translate then scale:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/translate https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/scale

ctx.translate(canvasWidth, 0);
ctx.scale(-1, 1);
Lyontine answered 10/8 at 10:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.