注意图片是使用 object-fit: cover 这种方式缩放过的
我试过下面的常规方法,但是得到的图片不太一样,因为浏览器缩放过的原因:
export const ImageToCanvas = (image: HTMLImageElement) => { const canvas = document.createElement('canvas'); canvas.width = image.width; canvas.height = image.height; canvas.getContext('2d')?.drawImage(image, 0, 0); return canvas;};export const canvasToImage = (canvas: HTMLCanvasElement) => { const image = new Image(); image.src = canvas.toDataURL('image/png'); return image;};export const downloadImage = (image: HTMLImageElement, name: string) => { const link = document.createElement('a'); link.download = name; link.href = image.src; link.click();};
/** * @param {{width: number, height: number}} containerSize 图片容器的宽高,单位px * @param {{width: number, height: number}} imageSize 图片宽高,单位px * @param {'fill'|'cover'|'contain'|'none'} [objectFit] * @return {[sx: number, sy: number, sWidth: number, sHeight: number, dx: number, dy: number, dWidth: number, dHeight: number]} */export function getDrawImagePosition(containerSize, imageSize, objectFit = 'fill') { // 图片宽高比 const imageRatio = imageSize.width / imageSize.height // 图片按容器宽高比缩放至占满整个容器 if (objectFit === 'fill') { return [0, 0, imageSize.width, imageSize.height, 0, 0, containerSize.width, containerSize.height] } // 保持宽高比缩放,图片最长边占满容器,不管图片是否足以被容器包含 if (objectFit === 'contain') { // 确定图片最长边 const longSide = imageRatio >= 1 ? 'width' : 'height' const scaleRatio = containerSize[longSide] / imageSize[longSide] // 最终绘制的图片尺寸 const scaleWidth = imageSize.width * scaleRatio const scaleHeight = imageSize.height * scaleRatio return [ 0, 0, imageSize.width, imageSize.height, longSide === 'width' ? 0 : (containerSize.width - scaleWidth) / 2, longSide === 'height' ? 0 : (containerSize.height - scaleHeight) / 2, scaleWidth, scaleHeight ] } // 保持宽高比缩放,直到恰好占满整个容器,居中显示,有可能发生裁剪,不管图片是否足以被容器包含 if (objectFit === 'cover') { const longSide = imageRatio >= 1 ? 'width' : 'height' const shortSide = imageRatio >= 1 ? 'height' : 'width' let scaleRatio = containerSize[shortSide] / imageSize[shortSide] // 最终绘制的图片尺寸 const scaleSize = { width: imageSize.width * scaleRatio, height: imageSize.height * scaleRatio } // 缩放后长边可能未占满容器,需要再次缩放 if (scaleSize[longSide] < containerSize[longSide]) { const ratio = containerSize[longSide] / scaleSize[longSide] scaleSize.width *= ratio scaleSize.height *= ratio scaleRatio = scaleSize.width / imageSize.width } // 原图映射到画布上的左上角相对于原图尺寸裁剪的距离 const clipWidth = (scaleSize.width - containerSize.width) / 2 / scaleRatio const clipHeight = (scaleSize.height - containerSize.height) / 2 / scaleRatio return [ clipWidth, clipHeight, imageSize.width - clipWidth, imageSize.height - clipHeight, 0, 0, containerSize.width, containerSize.height ] } // 保持原尺寸,居中显示,有可能发生裁剪 if (objectFit === 'none') { // 确定是容器还是图片更大 const horizontalDiff = (containerSize.width - imageSize.width) / 2 const verticalDiff = (containerSize.height - imageSize.height) / 2 return [ horizontalDiff >= 0 ? 0 : -horizontalDiff, verticalDiff >= 0 ? 0 : -verticalDiff, horizontalDiff >= 0 ? imageSize.width : imageSize.width + 2 * horizontalDiff, verticalDiff >= 0 ? imageSize.height : imageSize.height + 2 * verticalDiff, horizontalDiff >= 0 ? horizontalDiff : 0, verticalDiff >= 0 ? verticalDiff : 0, horizontalDiff >= 0 ? imageSize.width : containerSize.width, verticalDiff >= 0 ? imageSize.height : containerSize.height ] } throw new Error('unknown objectFit:' + objectFit)}
返回的参数就是drawImage的后8个参数
找了一个库,可以试试
https://www.npmjs.com/package/canvas-object-fit
import Canvas from 'canvas';import {drawImage} from 'canvas-object-fit'; const [width, height] = [200, 200];const canvas = new Canvas(width, height);const context = canvas.getContext('2d');const image = new Canvas.Image();image.src = await fs.readFileAsync(`${fixturesPath}/image.jpg`);drawImage(context, image, 0, 0, canvas.width, canvas.height, {objectFit: 'cover'});const buffer = canvas.toBuffer('png');
export const ImageToCanvas = (image: HTMLImageElement) => { const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); canvas.width = image.width; canvas.height = image.height; // 计算缩放比例和剪裁位置 const imgRatio = image.naturalWidth / image.naturalHeight; const canvasRatio = canvas.width / canvas.height; let sx, sy, sw, sh; if (imgRatio > canvasRatio) { sw = image.naturalHeight * canvasRatio; sh = image.naturalHeight; sx = (image.naturalWidth - sw) / 2; sy = 0; } else { sw = image.naturalWidth; sh = image.naturalWidth / canvasRatio; sx = 0; sy = (image.naturalHeight - sh) / 2; } context?.drawImage(image, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height); return canvas;};
问题内容: 我了解如何使用精灵,但是IMG标签不是必需的“ src”属性吗?我总是可以使用SPAN或其他标签并设置background / width / etc,但从语义上讲不会正确。 基本上,我想为IMG标签省略SRC,而只使用精灵,但是我担心HTML在技术上因此无效。谢谢。 问题答案: 关于语义正确性: 当图像具有语义时, 因此被认为是内容,请 使用IMG标签 (不带图片)和正确设置的ALT
使 UIScrollView 中的图片支持手势缩放。双击图片可以放大图片,或者pinch(捏合)手势可以缩放图片。基本原理是UIScrollView中嵌套UIScrollView,然后再嵌套UIImageView,可对UIImageView进行伸缩。 [Code4App.com]
就是通过F12开发者工具在网页中检查网络的那个图
本文向大家介绍js+html5绘制图片到canvas的方法,包括了js+html5绘制图片到canvas的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了js+html5绘制图片到canvas的方法。分享给大家供大家参考。具体实现方法如下: 更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript动画特效与技巧汇总》《JavaScript运动效果与技巧汇总
本文向大家介绍HTML5 canvas 9绘制图片实例详解,包括了HTML5 canvas 9绘制图片实例详解的使用技巧和注意事项,需要的朋友参考一下 绘制图片 Var image=new Image(); image.src=” http://img4.duitang.com/uploads/item/201406/25/20140625182321_4MTau.thumb.700_0.jpeg
问题内容: 我目前有一个迷宫游戏,它绘制一个5 x 5的正方形(占用屏幕的宽度并将其均匀分割)。然后,对于每个使用x和y坐标的框,我使用drawRect绘制彩色背景。 我遇到的问题是我现在需要在同一位置绘制图像,因此需要替换当前的纯背景色填充。 这是我当前用于drawRect的代码(一些示例): 然后,我还需要为画布中的所有其他正方形实现背景图像。该背景将在其顶部绘制简单的1px黑色线条,当前代码