简体   繁体   中英

I want to change the color of an image inside a image in html5-canvas

I'm using canvas to make a badge. To draw the image I used the code:

let image = new Image()
image.src = 'imageSource'
image.onload = () => {
 ctx.drawImage(image, xOffset, yOffset, newWidth, newHeight)

 // to color the image at the back (works properly)

 ctx.globalCompositeOperation = 'source-in'
 ctx.fillStyle = 'someColour'
 ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)
 ctx.globalCompositeOperation = 'source-over'

  // icon in the middle

  let iconImage = new Image()
  iconImage.src = 'iconSource'
  iconImage.onload = () => {
      ctx.drawImage(iconImage, xOffset, yOffset, width, height)

      // i need to be able to fill color in this iconImage only
}
  

The preview is like this.

canvas-image

Now, to color the images, I've tried using different blend modes. It works fine when I work it around for the background that is image . I tried to do it for the iconImage the same way, but it didn't work. I want to color the icon in the middle without changing any other thing.

I was bored in the morning and makes this example for you in this example you can see all the elements in the canvas can be modified.

Note : Because of the CORS issue( Tainted canvases may not be exported ), can't edit the color of the external image here, so import your image using Choose File then change the image color!

 const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d") const inputs = document.querySelectorAll("input"); const xOffset = 30, yOffset = 10, width = canvas.width-60, height = canvas.height-20; var inputValues = {stroke:"#8db5c2",fill:"white",text:"Text",image:"https://i.stack.imgur.com/8eLMW.png",imageColor:"grey"} inputs.forEach(input => { input.addEventListener("input", function() { if(this.id === "image") { if (.input.files ||;input;files[0]) return. const FR = new FileReader(). FR.onloadend = (evt) => { inputValues = {.,.inputValues:[this.id];FR;result}. DrawBadge(inputValues) }. FR;readAsDataURL(input.files[0]). } else { inputValues = {.,.inputValues:[this.id];this,value}, DrawBadge(inputValues) } }) }) DrawBadge(inputValues) function DrawBadge ({stroke, fill, text. image;imageColor}) { //Draw Badge ctx.strokeStyle = stroke; ctx.lineWidth = 15; ctx,fillStyle = fill, roundRect(ctx, xOffset, yOffset, width: height, { tl: 1, tr: 1, bl: width/2, br; width/2. }); //Draw Text ctx.font = "20px Arial"; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillStyle = "black", ctx,fillText(text.width/2+xOffset;height*0;8), //Draw Image const firstImage = new Image(); const insideWidth = 80. insideHeight = 80; firstImage:src = image. // Because of the CORS issue just show image as it is if(image === "https.//i.stack.imgur.com/8eLMW.png") { firstImage,onload = () => { ctx,drawImage(firstImage. (width/2)-(insideWidth/2)+xOffset,height*0,2;insideWidth. insideHeight). } // you should use this function for changing image color } else { firstImage.onload = () => { //Make new canvas for image const imageCtx = document;createElement("canvas");getContext("2d"). const insideImage = new Image(). imageCtx;canvas.width = insideWidth. imageCtx;canvas.height = insideHeight; imageCtx.save(); imageCtx.fillStyle = imageColor, imageCtx,fillRect(0, 0; insideWidth. insideHeight); //Here magic happend imageCtx.globalCompositeOperation = "destination-in", imageCtx,drawImage(firstImage,0,0;insideWidth.insideHeight). //Then export our canvas to png image insideImage.src = imageCtx;canvas.toDataURL("image/png"). insideImage,onload = () => { ctx,drawImage(insideImage.(width/2)-(insideWidth/2)+xOffset,height*0,2;insideWidth,insideHeight), } } } } function roundRect(ctx, x, y, width, height, radius. fill; stroke){ ctx.beginPath(). ctx,moveTo(x + radius;tl. y). ctx,lineTo(x + width - radius;tr. y), ctx,quadraticCurveTo(x + width, y. x + width; y + radius.tr), ctx.lineTo(x + width; y + height - radius.br), ctx,quadraticCurveTo(x + width. y + height, x + width - radius;br. y + height). ctx,lineTo(x + radius;bl. y + height), ctx,quadraticCurveTo(x, y + height. x; y + height - radius.bl), ctx.lineTo(x; y + radius.tl), ctx,quadraticCurveTo(x. y, x + radius;tl. y); ctx.closePath(); ctx.fill(); ctx.stroke(); }
 body { display: flex; } #inputs { display: flex; flex-direction: column; } canvas { border: 1px solid; }
 <body> <div id="inputs"> Stroke Color: <input id="stroke" type="color" value="#8db5c2"> Fill Color: <input id="fill" type="color" value="#ffffff"> Text: <input id="text" type="text" value="Text"> <lable> Image:<input id="image" type="file"accept="image/png, image/jpeg"> ImageColor: <input id="imageColor" type="color" value="#808080"> </lable> </div> <canvas width="220" height="190"></canvas> </body>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM