feat: cleanup screenshot thubnail

This commit is contained in:
Michal Szczepanski 2023-09-19 20:21:21 +02:00
parent 5d0b5da2c6
commit 402b88f760
6 changed files with 66 additions and 33 deletions

@ -27,6 +27,7 @@ import { ObjectStoreKeys } from '../../keys/object.store.keys';
import { ScreenshotFactory } from '../../factory/screenshot.factory';
import { UrlFactory } from '../../factory/url.factory';
import { fnSha256 } from '../../fn/fn-hash';
import { ImageResizeFactory } from '../../factory/image-resize.factory';
export class PdfAddCommand implements ICommand<Promise<void>> {
constructor(private value: FetchResponse<string>) {}
@ -35,11 +36,13 @@ export class PdfAddCommand implements ICommand<Promise<void>> {
const dt = Date.now();
const hash = fnSha256(this.value.data);
const screenshot = await ScreenshotFactory.takeScreenshot({
let screenshot = await ScreenshotFactory.takeScreenshot(document, window, ContentSettingsStore.settings);
screenshot = await ImageResizeFactory.resize2(
document,
window,
settings: ContentSettingsStore.settings
});
ScreenshotFactory.THUMB_SETTINGS,
ScreenshotFactory.THUMB_SIZE,
screenshot
);
const url = UrlFactory.newUrl();

@ -61,7 +61,12 @@ export class DownloadImageButton {
setTimeout(async () => {
let rect: ObjRectangleDto = this.model.ref.getBoundingClientRect();
if (this.model.canvas) rect = this.model.canvas.rect;
const screenshot = await ScreenshotFactory.takeScreenshot(this.model.doc, rect);
const screenshot = await ScreenshotFactory.takeScreenshot(
this.model.doc.document,
this.model.doc.window,
this.model.doc.settings,
rect
);
await this.downloadScreenshot(screenshot);
this.edit.showScreenshot();

@ -17,23 +17,33 @@
import { ObjRectangleDto, ObjSizeDto } from '../model/obj/obj-utils.dto';
import { PinDocument } from '../components/pin/model/pin-view.model';
import { fnConsoleLog } from '../fn/fn-console';
import { ScreenshotFormat } from '../environment';
export interface ScreenshotSettings {
screenshotFormat: ScreenshotFormat;
screenshotQuality: number;
}
export class ImageResizeFactory {
static resize2 = (doc: PinDocument, size: ObjSizeDto, b64image: string): Promise<string> => {
static resize2 = (
doc: Document,
settings: ScreenshotSettings,
size: ObjSizeDto,
b64image: string
): Promise<string> => {
return new Promise<string>((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
try {
const can = doc.document.createElement('canvas');
const can = doc.createElement('canvas');
const wr = size.width / img.naturalWidth;
const hr = size.height / img.naturalHeight;
fnConsoleLog('AAAAAAAAAAAAAAAAAAAAAAAAAaa', wr, hr);
can.width = img.naturalWidth * wr;
can.height = img.naturalHeight * hr;
const ctx = can.getContext('2d');
ctx?.drawImage(img, 0, 0, can.width, can.height);
b64image = can.toDataURL(`image/${doc.settings.screenshotFormat}`, doc.settings.screenshotQuality);
b64image = can.toDataURL(`image/${settings.screenshotFormat}`, settings.screenshotQuality);
} finally {
window.URL.revokeObjectURL(b64image);
img.onerror = null;
@ -52,23 +62,29 @@ export class ImageResizeFactory {
img.src = b64image;
});
};
static resize = (doc: PinDocument, size: ObjRectangleDto, b64image: string): Promise<string> => {
static resize = (
doc: Document,
win: Window,
settings: ScreenshotSettings,
size: ObjRectangleDto,
b64image: string
): Promise<string> => {
const rect = {
x: size.x,
y: size.y,
width: size.width,
height: Math.min(size.height, doc.window.innerHeight - size.y)
height: Math.min(size.height, win.innerHeight - size.y)
};
return new Promise<string>((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
try {
const can = doc.document.createElement('canvas');
const can = doc.createElement('canvas');
can.width = rect.width;
can.height = rect.height;
const wr = img.naturalWidth / doc.window.innerWidth;
const hr = img.naturalHeight / doc.window.innerHeight;
const wr = img.naturalWidth / win.innerWidth;
const hr = img.naturalHeight / win.innerHeight;
const ctx = can.getContext('2d');
ctx?.drawImage(
img,
@ -81,7 +97,7 @@ export class ImageResizeFactory {
rect.width,
rect.height
);
b64image = can.toDataURL(`image/${doc.settings.screenshotFormat}`, doc.settings.screenshotQuality);
b64image = can.toDataURL(`image/${settings.screenshotFormat}`, settings.screenshotQuality);
} finally {
window.URL.revokeObjectURL(b64image);
img.onerror = null;

@ -16,22 +16,36 @@
*/
import { BrowserApi } from '@pinmenote/browser-api';
import { BusMessageType } from '../model/bus.model';
import { ImageResizeFactory } from './image-resize.factory';
import { ObjRectangleDto } from '../model/obj/obj-utils.dto';
import { ImageResizeFactory, ScreenshotSettings } from './image-resize.factory';
import { ObjRectangleDto, ObjSizeDto } from '../model/obj/obj-utils.dto';
import { ObjUrlDto } from '../model/obj/obj.dto';
import { PinDocument } from '../components/pin/model/pin-view.model';
import { TinyDispatcher } from '@pinmenote/tiny-dispatcher';
import { fnConsoleLog } from '../fn/fn-console';
export class ScreenshotFactory {
static takeScreenshot = async (doc: PinDocument, rect?: ObjRectangleDto, url?: ObjUrlDto): Promise<string> => {
static readonly THUMB_SETTINGS: ScreenshotSettings = {
screenshotFormat: 'jpeg',
screenshotQuality: 80
};
static readonly THUMB_SIZE: ObjSizeDto = {
width: 640,
height: 360
};
static takeScreenshot = async (
doc: Document,
win: Window,
settings: ScreenshotSettings,
rect?: ObjRectangleDto,
url?: ObjUrlDto
): Promise<string> => {
return new Promise((resolve, reject) => {
// Crop screenshot function
TinyDispatcher.getInstance().addListener<string>(
BusMessageType.CONTENT_TAKE_SCREENSHOT,
async (event: string, key: string, screenshot: string) => {
TinyDispatcher.getInstance().removeListener(event, key);
if (rect) screenshot = await ImageResizeFactory.resize(doc, rect, screenshot);
if (rect) screenshot = await ImageResizeFactory.resize(doc, win, settings, rect, screenshot);
resolve(screenshot);
}
);
@ -47,7 +61,7 @@ export class ScreenshotFactory {
.then(() => {
// We handle it above, inside dispatcher
})
.catch((e) => {
.catch((e: any) => {
fnConsoleLog('ScreenshotFactory->sendTakeScreenshot->error', e);
reject('PROBLEM !!!');
});

@ -61,15 +61,12 @@ export class ContentPageSnapshotCreateCommand implements ICommand<Promise<PageSn
isPartial = true;
}
let screenshot = await ScreenshotFactory.takeScreenshot(
{ settings: this.settings, document, window },
rect,
this.url
);
let screenshot = await ScreenshotFactory.takeScreenshot(document, window, this.settings, rect, this.url);
if (rect.width > 640 || rect.height > 360) {
screenshot = await ImageResizeFactory.resize2(
{ settings: this.settings, document, window },
{ width: 640, height: 360 },
document,
ScreenshotFactory.THUMB_SETTINGS,
ScreenshotFactory.THUMB_SIZE,
screenshot
);
}

@ -35,11 +35,9 @@ export class PinFactory {
): Promise<ObjPinDto> => {
const rect = canvas ? canvas.rect : XpathFactory.computeRect(ref);
const screenshot = await ScreenshotFactory.takeScreenshot(
{
settings: ContentSettingsStore.settings,
document,
window
},
document,
window,
ContentSettingsStore.settings,
rect,
url
);