由于没有特别的原因,除了不熟悉canvas
和CanvasRenderingContext2D.drawImage()
之外,我尝试编写一个函数,该函数将采用<image>
元素和其他选项,例如作为<image>
应该被'切片'的'行'和'cols'的数量。
目前,作为第一步,应将“切片”图片部分转移到<canvas>
附加的已创建document
元素中。
虽然这个功能有效但是我没有改变默认的行数和列数 - 但结果却因某种原因被裁剪,例如这个源图像:
缩放到这个:
我完全接受这可能是我的数学应用中的混乱,并且几乎肯定必须在CanvasRenderingContext2D.drawImage()
范围内,因此可能位于for
循环中但是已经盯着它,并且喝了几杯咖啡,我还没看到我的傻瓜在哪里。
我的代码片段:
// Using ES6/ECMAScript 2015 'let' operator
function imageFragment(opts) {
// defaults for the function (to be overridden)
// by user supplied values (if any are passed):
let settings = {
'source': document.querySelector('img'),
'rows': 2,
'cols': 2,
'trim': true
};
// Using Object.keys to retrieve the keys of the
// opts Object, or an empty object (without keys)
// should no opts Object be supplied;
// using Array.prototype.forEach() to iterate over
// the Array of keys, using Arrow syntax, to
// update the defaults settings to the user-defined
// settings:
Object.keys(opts || {}).forEach(key => settings[key] = opts[key]);
let image = settings.source,
frame = document.createElement('div'),
canvas = document.createElement('canvas'),
imageHeight = image.clientHeight,
imageWidth = image.clientWidth,
tileHeight = parseInt(imageHeight / settings.rows, 10),
tileWidth = parseInt(imageWidth / settings.cols, 10),
// following two variables, heightRemainder and
// widthRemainder, are not currently used, but here
// in anticipation of settings.trim being set to 'false':
heightRemainder = imageHeight % tileHeight,
widthRemainder = imageWidth % tileWidth,
nCols = settings.cols + (settings.trim === true ? 0 : 1),
nRows = settings.rows + (settings.trim === true ? 0 : 1),
context = canvas.getContext('2d');
// updating properties of the frame and canvas
// element nodes:
frame.classList.add('canvasWrapper');
canvas.style.width = nCols * tileWidth + 'px';
canvas.style.height = nRows * tileHeight + 'px';
canvas.classList.add('tile');
// using nested for loops to iterate over each of
// the 'columns' within each 'row' (I strongly
// believe this could be revised, and hopefully
// simplified):
for (let r = 0; r < nRows; r++) {
for (let c = 0; c < nCols; c++) {
// defining the section of the image to copy,
// image: the source image,
// (r * tileWidth): the x-offset position of
// the upper-left corner of the 'segment' to
// copy on this iteration,
// (c * tileHeight): the y-offset position of
// the upper-left corner of the 'segment',
// tileWidth: the width of the 'segment' to copy,
// tilleHeight: the height of the 'segment' to copy,
// (r * tileWidth): the target horizontal position of the
// upper-left corner of the copied 'segment' in
// the target (the canvas),
// (c * tileHeight): the target vertical position of
// the upper-left corner of the copied 'segment' in the
// target,
// tileWidth and tileHeight: the width and height of
// the copied segment in the target:
context.drawImage(image, (r * tileWidth), (c * tileHeight), tileWidth, tileHeight, (r * tileWidth), (c * tileHeight), tileWidth, tileHeight);
}
}
// appending the canvas to the frame:
frame.appendChild(canvas);
// inserting the frame ahead of the image within
// the image's parentNode:
image.parentNode.insertBefore(frame, image);
}
imageFragment({
'rows': 3
});
<img src="https://i.imgur.com/iWKad22m.jpg" />
并且,在猜测之前,经典的脸型是专门为这个问题选择的,但确切地复制了“原始”源图像的问题。
答案 0 :(得分:0)
您应该设置画布大小。目前,您只使用CSS调整默认的300x150大小。
canvas.width = imageWidth;
canvas.height = imageHeight;
然后你不应该强迫{rows: 3}
。
// Using ES6/ECMAScript 2015 'let' operator
function imageFragment(opts) {
// defaults for the function (to be overridden)
// by user supplied values (if any are passed):
let settings = {
'source': document.querySelector('img'),
'rows': 2,
'cols': 2,
'trim': true
};
// Using Object.keys to retrieve the keys of the
// opts Object, or an empty object (without keys)
// should no opts Object be supplied;
// using Array.prototype.forEach() to iterate over
// the Array of keys, using Arrow syntax, to
// update the defaults settings to the user-defined
// settings:
Object.keys(opts || {}).forEach(key => settings[key] = opts[key]);
let image = settings.source,
frame = document.createElement('div'),
canvas = document.createElement('canvas'),
imageHeight = image.clientHeight,
imageWidth = image.clientWidth,
tileHeight = parseInt(imageHeight / settings.rows, 10),
tileWidth = parseInt(imageWidth / settings.cols, 10),
// following two variables, heightRemainder and
// widthRemainder, are not currently used, but here
// in anticipation of settings.trim being set to 'false':
heightRemainder = imageHeight % tileHeight,
widthRemainder = imageWidth % tileWidth,
nCols = settings.cols + (settings.trim === true ? 0 : 1),
nRows = settings.rows + (settings.trim === true ? 0 : 1),
context = canvas.getContext('2d');
// updating properties of the frame and canvas
// element nodes:
frame.classList.add('canvasWrapper');
canvas.width = imageWidth;
canvas.height = imageHeight;
canvas.style.width = nCols * tileWidth + 'px';
canvas.style.height = nRows * tileHeight + 'px';
canvas.classList.add('tile');
// using nested for loops to iterate over each of
// the 'columns' within each 'row' (I strongly
// believe this could be revised, and hopefully
// simplified):
for (let r = 0; r < nRows; r++) {
for (let c = 0; c < nCols; c++) {
// defining the section of the image to copy,
// image: the source image,
// (r * tileWidth): the x-offset position of
// the upper-left corner of the 'segment' to
// copy on this iteration,
// (c * tileHeight): the y-offset position of
// the upper-left corner of the 'segment',
// tileWidth: the width of the 'segment' to copy,
// tilleHeight: the height of the 'segment' to copy,
// (r * tileWidth): the target horizontal position of the
// upper-left corner of the copied 'segment' in
// the target (the canvas),
// (c * tileHeight): the target vertical position of
// the upper-left corner of the copied 'segment' in the
// target,
// tileWidth and tileHeight: the width and height of
// the copied segment in the target:
context.drawImage(image, (r * tileWidth), (c * tileHeight), tileWidth, tileHeight, (r * tileWidth), (c * tileHeight), tileWidth, tileHeight);
}
}
// appending the canvas to the frame:
frame.appendChild(canvas);
// inserting the frame ahead of the image within
// the image's parentNode:
image.parentNode.insertBefore(frame, image);
}
imageFragment({
// 'rows' : 3
});
<img src="https://i.imgur.com/iWKad22m.jpg" />