在Firefox中,默认的新标签页包含网页建议列表,其中包含网页域名和缩略图。缩略图可以是图标(如果足够大),也可以是网页的预览图像。例如example。
我正在尝试使用类似于Firefox的缩略图创建我自己的新标签页版本。互联网中的大多数解决方案都建议部署服务器(例如via node.js)或使用服务(例如URL2PNG)。
因此,我很好奇Firefox如何在客户端生成缩略图(如果它实际上是服务器端,请纠正我)。是否有任何推荐的库/框架(例如html2canvas虽然它无法截取其他网站)?
答案 0 :(得分:0)
不确定这对你的情况有多大,但它使用(非标准的,内部的)CanvasRenderingContext2D.drawWindow() API将窗口的快照渲染到中间画布,然后将其复制到目标缩小的画布元素。 / p>
您可以在toolkit/components/thumbnails/PageThumbUtils.jsm中看到执行此操作的代码:
/** *
* Given a browser window, this creates a snapshot of the content
* and returns a canvas with the resulting snapshot of the content
* at the thumbnail size. It has to do this through a two step process:
*
* 1) Render the content at the window size to a canvas that is 2x the thumbnail size
* 2) Downscale the canvas from (1) down to the thumbnail size
*
* This is because the thumbnail size is too small to render at directly,
* causing pages to believe the browser is a small resolution. Also,
* at that resolution, graphical artifacts / text become very jagged.
* It's actually better to the eye to have small blurry text than sharp
* jagged pixels to represent text.
*
* @params aWindow - the window to create a snapshot of.
* @params aDestCanvas destination canvas to draw the final
* snapshot to. Can be null.
* @param aArgs (optional) Additional named parameters:
* fullScale - request that a non-downscaled image be returned.
* @return Canvas with a scaled thumbnail of the window.
*/
createSnapshotThumbnail(aWindow, aDestCanvas, aArgs) {
if (Cu.isCrossProcessWrapper(aWindow)) {
throw new Error("Do not pass cpows here.");
}
let fullScale = aArgs ? aArgs.fullScale : false;
let [contentWidth, contentHeight] = this.getContentSize(aWindow);
let [thumbnailWidth, thumbnailHeight] = aDestCanvas ?
[aDestCanvas.width, aDestCanvas.height] :
this.getThumbnailSize(aWindow);
// If the caller wants a fullscale image, set the desired thumbnail dims
// to the dims of content and (if provided) size the incoming canvas to
// support our results.
if (fullScale) {
thumbnailWidth = contentWidth;
thumbnailHeight = contentHeight;
if (aDestCanvas) {
aDestCanvas.width = contentWidth;
aDestCanvas.height = contentHeight;
}
}
let intermediateWidth = thumbnailWidth * 2;
let intermediateHeight = thumbnailHeight * 2;
let skipDownscale = false;
// If the intermediate thumbnail is larger than content dims (hiDPI
// devices can experience this) or a full preview is requested render
// at the final thumbnail size.
if ((intermediateWidth >= contentWidth ||
intermediateHeight >= contentHeight) || fullScale) {
intermediateWidth = thumbnailWidth;
intermediateHeight = thumbnailHeight;
skipDownscale = true;
}
// Create an intermediate surface
let snapshotCanvas = this.createCanvas(aWindow, intermediateWidth,
intermediateHeight);
// Step 1: capture the image at the intermediate dims. For thumbnails
// this is twice the thumbnail size, for fullScale images this is at
// content dims.
// Also by default, canvas does not draw the scrollbars, so no need to
// remove the scrollbar sizes.
let scale = Math.min(Math.max(intermediateWidth / contentWidth,
intermediateHeight / contentHeight), 1);
let snapshotCtx = snapshotCanvas.getContext("2d");
snapshotCtx.save();
snapshotCtx.scale(scale, scale);
snapshotCtx.drawWindow(aWindow, 0, 0, contentWidth, contentHeight,
PageThumbUtils.THUMBNAIL_BG_COLOR,
snapshotCtx.DRAWWINDOW_DO_NOT_FLUSH);
snapshotCtx.restore();
// Part 2: Downscale from our intermediate dims to the final thumbnail
// dims and copy the result to aDestCanvas. If the caller didn't
// provide a target canvas, create a new canvas and return it.
let finalCanvas = aDestCanvas ||
this.createCanvas(aWindow, thumbnailWidth, thumbnailHeight);
let finalCtx = finalCanvas.getContext("2d");
finalCtx.save();
if (!skipDownscale) {
finalCtx.scale(0.5, 0.5);
}
finalCtx.drawImage(snapshotCanvas, 0, 0);
finalCtx.restore();
return finalCanvas;
},