简体   繁体   中英

Delete a vertical line worth of pixels

I am trying to delete a vertical line that is 10 px in width and the height of the image.I am using a canvas. I cannot post this to jsfiddle because i cannot load the image.

var canvas = document.createElement("canvas");

canvas.height = 200;
canvas.width = 200;
Caman(canvas, "studipo.jpg", function () {
     var base64encoded = GetResizedImage(canvas, 200, 200, 200, 160);       
});


function GetResizedImage(canvas, width, height, croppingWidth, croppingheight) {
var ctx = canvas.getContext("2d");

var oldid = ctx.getImageData(0, 0, width, height);

var newCanvas = document.createElement("canvas");

newCanvas.width = croppingWidth;

newCanvas.height = croppingheight;

var newContext2d = newCanvas.getContext("2d");

var vnewid = newContext2d.createImageData(width, height);

var oldArray = Array.from(oldid.data);

console.log(oldArray);

var arrayToInsert = [];


for (var y = 0; y < height; ++y) {
    for (var x = 0; x < width; ++x) {
        if (y > 90 && y < 130) { // this is how we remove a horizontal line worth of 20 pixels in width. 

        }
        else {
            var index = (y * width + x) * 4; // index of the current pixel                       
            arrayToInsert.push(oldArray[index]);
            arrayToInsert.push(oldArray[index + 1]);
            arrayToInsert.push(oldArray[index + 2]);
            arrayToInsert.push(oldArray[index + 3]);
        }
    }
}

for (var i = 0; i < 200; i = i + 1) {


    for (var j = 0; j < 160; j++) {
        var index = (i * width + j) * 4;
        if (j < 80 && j > 70) {

            // this draw a vertical line of pixels that have (0,0,0,0) in rgb+a in the middle of the image.
            arrayToInsert[index] = 0;
            arrayToInsert[index + 1] = 0;
            arrayToInsert[index + 2] = 0;
            arrayToInsert[index + 3] = 0


            //   uncomment this.
            //   arrayToInsert.splice (index, 4); 
            //   this does not work for some reason, but it should

        }
    }
}

vnewid.data.set(arrayToInsert);
newContext2d.putImageData(vnewid, 0, 0, 0, 0, 200, 160);

var newC = newCanvas.toDataURL();
console.log(newC);

// take this console.log base64 encoded image and put it here.

// https://codebeautify.org/base64-to-image-converter

}

At this line here.

                arrayToInsert[index] = 0;
                arrayToInsert[index + 1] = 0;
                arrayToInsert[index + 2] = 0;
                arrayToInsert[index + 3] = 0;

I can draw a line a vertical line with this.However if i try to remove those pixels altogether, the image data gets corrupted and it makes no sense and i do not understand why.

arrayToInsert.splice (index, 4); 

Instead of making all those pixels ( 0 0 0 0 ), i would like to remove them so that the image is cropped.

Here is the link to 3 files ( a html, the photo used and the js.)

https://drive.google.com/open?id=0B06HbozeqdkZXzNDUTJKelVZMmc

Note: I want to crop in the middle of the image, not on the edge of the image.

Like this cake here.

http://static2.businessinsider.com/image/57ee8fa7dd0895e5358b4d30-907/cutting%20cake%20into%20rectangles%202%20skitch.jpg

I would cut a rectangle the i would press the 2 parts of the cake into each other, so it becomes a single cake, except with a cropped out rectangle in the middle.

From what I've understood what you need is to make transparent that part of the image, isn't?

arrayToInsert[index + 3] = 0;

This will do the job for you, as the fourth value is transparency. Ps: I've tested here and it worked fine. I am posting a jsfiddle soon

You're getting messed up when you create the ImageData for the new canvas. Look at this line:

var vnewid = newContext2d.createImageData(width, height);

Right there you're saying, "This data that I'm going to create will be the exact same size as the original." You're creating a 200x200 data object that you're trying to fill with 190x160 pixels.

That's just fine if all you want to do is trim off some height. The ImageData will be interpreted left-to-right, top-to-bottom. For the first 160 rows, it has all the data in each row. For the rest, it has no data, so it just assumes that area is blank. All good.

When you tried to trim off horizontal stuff, that caused it to look funky. Each row was taking progressively 10px more and 10px more from the next row, making the image look skewed and jagged.

I fixed this by changing that call to

var vnewid = newContext2d.createImageData(croppingWidth, croppingheight);

But there's a few more problems.

  • The call to GetResizedImage() doesn't take into account that there are 10 fewer pixels. There should be a 190 in there.
  • When you put the ImageData in newContext2d , you again need to put in 190 or use croppingWidth .

Last but not least, you've got an off-by-one problem when you're cropping. You're cropping out 39 pixels and 19 pixels. Observe:

if (y > 90 && y < 130) {

That will take pixels starting at 91 and stopping after 129. If you change either of those to a >= or <= , it would be fine.

Here's some improved code. Since I didn't feel like getting an image, I improvised with a red circle. Note that you can put the data URL in an <img> instead of having to use some other site.

 var canvas = document.createElement("canvas"); function fillSrc(canvas) { var ctx = canvas.getContext('2d'); ctx.fillStyle = 'red'; ctx.beginPath(); ctx.ellipse(100, 100, 100, 100, Math.PI * 2, 0, Math.PI * 2); ctx.fill(); } canvas.height = 200; canvas.width = 200; document.body.appendChild(canvas); fillSrc(canvas); var base64encoded = GetResizedImage(canvas, 200, 200, 190, 160); function GetResizedImage(canvas, width, height, croppingWidth, croppingheight) { var ctx = canvas.getContext("2d"); var oldid = ctx.getImageData(0, 0, width, height); var newCanvas = document.createElement("canvas"); newCanvas.width = croppingWidth; newCanvas.height = croppingheight; var newContext2d = newCanvas.getContext("2d"); var vnewid = newContext2d.createImageData(croppingWidth, croppingheight); var oldArray = Array.from(oldid.data); console.log(oldArray); var arrayToInsert = []; for (var y = 0; y < height; ++y) { for (var x = 0; x < width; ++x) { if (y >= 90 && y < 130) { // Take out 40 pixels in a vertical section } else if (x >= 70 && x < 80) { // Take out 20 pixels in a horizontal section } else { var index = (y * width + x) * 4; // index of the current pixel arrayToInsert.push(oldArray[index]); arrayToInsert.push(oldArray[index + 1]); arrayToInsert.push(oldArray[index + 2]); arrayToInsert.push(oldArray[index + 3]); } } } console.log(arrayToInsert); vnewid.data.set(arrayToInsert); newContext2d.putImageData(vnewid, 0, 0, 0, 0, croppingWidth, croppingheight); var newC = newCanvas.toDataURL(); document.getElementById('test').src = newC; console.log(newC); // take this console.log base64 encoded image and put it here. // https://codebeautify.org/base64-to-image-converter } 
 <img id="test" /> 

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