复制图片到剪贴板
源码
ts
import { loadImage } from '../load-image/code'
import { imageToCanvas } from '../image-to-canvas/code'
import { canvasToBlob } from '../canvas-to-blob/code'
import { copyFileToClipboard } from '../copy-file/code'
/**
* 复制图片到剪贴板
* @example
* copyImageToClipboard('https://example.com/image.png')
* copyImageToClipboard(image)
*/
export function copyImageToClipboard(url: string): Promise<void>
export function copyImageToClipboard(
image: HTMLImageElement,
): Promise<void>
export async function copyImageToClipboard(
urlOrImage: string | HTMLImageElement,
) {
if (!navigator.clipboard) {
throw new Error('Clipboard API is not supported in current browser')
}
const image =
typeof urlOrImage === 'string'
? await loadImage(urlOrImage, { crossOrigin: 'anonymous' })
: urlOrImage
const canvas = imageToCanvas(image)
const blob = await canvasToBlob(canvas)
await copyFileToClipboard(blob)
}源码用到的函数
loadImage
ts
export interface LoadImageOptions {
/**
* 是否撤销
*/
revoke?: boolean
/**
* 图片宽度
*/
width?: number
/**
* 图片高度
*/
height?: number
/**
* 跨域
*/
crossOrigin?: 'anonymous' | 'use-credentials' | ''
}
/**
* 加载图片
*/
export async function loadImage(
src: string,
options?: LoadImageOptions,
): Promise<HTMLImageElement> {
const { revoke = false, width, height, crossOrigin } = options || {}
return new Promise<HTMLImageElement>((resolve, reject) => {
const img = new Image(width, height)
if (crossOrigin) img.crossOrigin = crossOrigin
img.onload = () => {
resolve(img)
if (revoke) URL.revokeObjectURL(img.src)
}
img.onerror = () => {
reject(new Error('load image error'))
if (revoke) URL.revokeObjectURL(img.src)
}
img.src = src
})
}imageToCanvas
ts
/**
* Image 转 Canvas
*/
export function imageToCanvas(image: HTMLImageElement) {
const canvas = document.createElement('canvas')
canvas.width = image.naturalWidth
canvas.height = image.naturalHeight
const ctx = canvas.getContext('2d')
if (!ctx) {
throw new Error('Canvas 2D API is not supported in current browser')
}
ctx.drawImage(image, 0, 0)
return canvas
}canvasToBlob
ts
/**
* Canvas 转 Blob
* @param canvas 需要转换的 HTMLCanvasElement 元素
* @param type MIME 类型(如 'image/png', 'image/jpeg' 等)
* @param quality 图像质量,取值范围 0-1
* @example
* const blob = await canvasToBlob(canvas, 'image/png', 0.8)
*/
export function canvasToBlob(
canvas: HTMLCanvasElement,
type?: string,
quality?: number,
): Promise<Blob> {
return new Promise<Blob>((resolve, reject) => {
canvas.toBlob(
(blob) => {
if (blob) {
resolve(blob)
} else {
reject(new Error('canvas to blob error'))
}
},
type,
quality,
)
})
}copyFileToClipboard
ts
/**
* 复制图片到剪贴板
*/
export async function copyFileToClipboard(file: File | Blob) {
if (!navigator.clipboard) {
throw new Error('Clipboard API is not supported in current browser')
}
if (!file.type) {
throw new Error('File type is empty')
}
const item = new ClipboardItem({ [file.type]: file })
await navigator.clipboard.write([item])
}