最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - html5 image cropping - Stack Overflow

programmeradmin0浏览0评论

I'm using context-blender to apply a multiply effect on the first 192 pixels of the html background-image with a fixed color to achieve a transparency effect on the header of the page.

On the html I have 2 canvas. One for the part of the image to apply the multiply effect and one for the color.

On the javascript, after setting the color of the color-canvas and the width of both canvas to the window.innerWidth I'm getting the background image with:

imageObj.src = $('html').css('background-image').replace(/^url|[\(\)]/g, '');

Now es the problem. I want to draw a cropped image to the image to the image-canvas so I can apply the multiply effect. I'm trying to do the following:

imageObj.onload = function(){
    // getting the background-image height
    var imageHeight = window.innerWidth * imageObj.height / imageObj.width;

    // get the corresponding pixels of the source image that correspond to the first 192 pixels of the background-image
    var croppedHeight = 192 * imageObj.height / imageHeight;

    // draw the image to the canvas
    imageCanvas.drawImage(imageObj, 0, 0, imageObj.width, croppedHeight, 0, 0, window.innerWidth, 192);

    // apply the multiply effect
    colorCanvas.blendOnto( imageCanvas, 'multiply');
}

But I'm doing something wrong getting the cropped height.

Ex: For an 1536x1152 image and a 1293x679 browser container, the value I'm getting for the source cropped height is 230 but to get the correct crop I need to use something around 296.

Edit:

I'm using background-size: cover on the css to create the background-image

Edit2:

I created a fiddle to illustrate the problem. If you unment the line //cHeight *= magicConstant; the cropped image looks a lot better but things stop making sense. I removed the multiply effect on the fiddler but that's not required to reproduce the problem. I also noticed that the behavior changed if I remove the second canvas from the URL.

Btw, this behavior happened with google chrome, but I think the same thing happens on safari and firefox.

I'm using context-blender to apply a multiply effect on the first 192 pixels of the html background-image with a fixed color to achieve a transparency effect on the header of the page.

On the html I have 2 canvas. One for the part of the image to apply the multiply effect and one for the color.

On the javascript, after setting the color of the color-canvas and the width of both canvas to the window.innerWidth I'm getting the background image with:

imageObj.src = $('html').css('background-image').replace(/^url|[\(\)]/g, '');

Now es the problem. I want to draw a cropped image to the image to the image-canvas so I can apply the multiply effect. I'm trying to do the following:

imageObj.onload = function(){
    // getting the background-image height
    var imageHeight = window.innerWidth * imageObj.height / imageObj.width;

    // get the corresponding pixels of the source image that correspond to the first 192 pixels of the background-image
    var croppedHeight = 192 * imageObj.height / imageHeight;

    // draw the image to the canvas
    imageCanvas.drawImage(imageObj, 0, 0, imageObj.width, croppedHeight, 0, 0, window.innerWidth, 192);

    // apply the multiply effect
    colorCanvas.blendOnto( imageCanvas, 'multiply');
}

But I'm doing something wrong getting the cropped height.

Ex: For an 1536x1152 image and a 1293x679 browser container, the value I'm getting for the source cropped height is 230 but to get the correct crop I need to use something around 296.

Edit:

I'm using background-size: cover on the css to create the background-image

Edit2:

I created a fiddle to illustrate the problem. If you unment the line //cHeight *= magicConstant; the cropped image looks a lot better but things stop making sense. I removed the multiply effect on the fiddler but that's not required to reproduce the problem. I also noticed that the behavior changed if I remove the second canvas from the URL.

Btw, this behavior happened with google chrome, but I think the same thing happens on safari and firefox.

Share Improve this question edited Apr 18, 2012 at 10:50 Starx 79.1k50 gold badges187 silver badges265 bronze badges asked Apr 12, 2012 at 9:34 dcarneirodcarneiro 7,18012 gold badges55 silver badges74 bronze badges 2
  • Would you be able to create an example on jsfiddle? Might help us e up with an answer for you. Also Is the behaviour (getting 230px vs 296px) consistent across multiple browsers? – Marc Gagne Commented Apr 16, 2012 at 11:24
  • @MarcGagne I added the example to the question – dcarneiro Commented Apr 16, 2012 at 16:25
Add a ment  | 

2 Answers 2

Reset to default 5 +50

OK, I've fixed it. Man was that hard! Mainly because you forgot to set the imageCanvas' canvas height. It also didn't help that the image has a white border. I spent a hell of a lot of time trying to figure out where the padding was ing from.

So to start, for the case of the fiddle, in function doBlending(), set imageCanvas.canvas.height = height;

Then the calculations in crop() need to cover 2 possibilities. Is the image being scaled for height and truncated on the left or scaled for width and truncated on the bottom? I'm not going to write both for you, but here's the one for the case where it is scaled for height:

function crop(imageObj, imageCanvas, colorCanvas) {
    // Assumes bg image is scaled for hight
    var scale = imageObj.height / window.innerHeight; 
    var targetHeight = imageCanvas.canvas.height;
    var targetWidth = window.innerWidth;

    imageCanvas.drawImage(imageObj, 
                          0, 0, targetWidth * scale, targetHeight * scale,
                          0, 0, targetWidth, targetHeight);
}

I really have no idea where you came up with the scaling factors in your example. The image is going to be scaled by multiplying both the x and y dimensions by some scale factor. That's how you preserve the aspect ratio. The scale factor will be the larger of the one to make the height of the image match the height of the window and the one to make the width of the image match the width of the window.

I think it may not be valid for you to be using window inner dimensions here. Since cover will maintain the aspect ratio of the background image it means that both of its dimensions may not be fully displayed. So if you are trying to transform between aspect ratios to determine where to clip, you would have to account for the fact that the image may flow out of the window borders.

发布评论

评论列表(0)

  1. 暂无评论