From 33bfd38be618eb2ff67c626e9063a1cad634ce09 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Fri, 6 May 2022 21:54:51 +0200 Subject: [PATCH 1/3] (#400) Implement fetchFromUrl + tests --- lib/imageResources.function.spec.ts | 45 ++++++++++++++++++++++++++++- lib/imageResources.function.ts | 31 ++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/lib/imageResources.function.spec.ts b/lib/imageResources.function.spec.ts index a64600aa..9bd887f0 100644 --- a/lib/imageResources.function.spec.ts +++ b/lib/imageResources.function.spec.ts @@ -1,8 +1,9 @@ -import {loadImageResource} from "./imageResources.function"; +import {fetchFromUrl, loadImageResource} from "./imageResources.function"; import {mockPartial} from "sneer"; import {ProviderRegistry} from "./provider/provider-registry.class"; import {ImageReader} from "./provider"; import {join} from "path"; +import {ColorMode} from "./colormode.enum"; const loadMock = jest.fn(); const providerRegistryMock = mockPartial({ @@ -25,4 +26,46 @@ describe('imageResources', () => { // THEN expect(loadMock).toBeCalledWith(join(resourceDirectoryPath, imageFileName)); }); +}); + +describe('fetchFromUrl', () => { + it('should throw on malformed URLs', async () => { + // GIVEN + const malformedUrl = "foo"; + + // WHEN + const SUT = () => fetchFromUrl(malformedUrl); + + // THEN + await expect(SUT).rejects.toThrowError("Invalid URL"); + }); + + it('should throw on non-image URLs', async () => { + // GIVEN + const nonImageUrl = 'https://www.npmjs.com/package/jimp'; + + // WHEN + const SUT = () => fetchFromUrl(nonImageUrl); + + // THEN + await expect(SUT).rejects.toThrowError('Could not find MIME for Buffer'); + }); + + it('should return an RGB image from a valid URL', async () => { + // GIVEN + const validImageUrl = 'https://github.com/nut-tree/nut.js/raw/master/.gfx/nut.png'; + const expectedDimensions = { + width: 502, + height: 411 + }; + const expectedColorMode = ColorMode.RGB; + + // WHEN + const rgbImage = await fetchFromUrl(validImageUrl); + + // THEN + expect(rgbImage.colorMode).toBe(expectedColorMode); + expect(rgbImage.width).toBe(expectedDimensions.width); + expect(rgbImage.height).toBe(expectedDimensions.height); + }); }); \ No newline at end of file diff --git a/lib/imageResources.function.ts b/lib/imageResources.function.ts index 96ce588e..2fc7f04b 100644 --- a/lib/imageResources.function.ts +++ b/lib/imageResources.function.ts @@ -1,7 +1,38 @@ import {join, normalize} from "path"; import {ProviderRegistry} from "./provider/provider-registry.class"; +import {URL} from "url"; +import {Image} from "./image.class"; +import Jimp from "jimp"; +import {ColorMode} from "./colormode.enum"; export function loadImageResource(providerRegistry: ProviderRegistry, resourceDirectory: string, fileName: string) { const fullPath = normalize(join(resourceDirectory, fileName)); return providerRegistry.getImageReader().load(fullPath); +} + +export async function fetchFromUrl(url: string | URL): Promise { + let imageUrl: URL; + if (url instanceof URL) { + imageUrl = url; + } else { + try { + imageUrl = new URL(url); + } catch (e) { + throw e; + } + } + return Jimp.read(imageUrl.href) + .then((image) => { + return new Image( + image.bitmap.width, + image.bitmap.height, + image.bitmap.data, + 4, + imageUrl.href, + ColorMode.RGB + ); + }) + .catch(err => { + throw err; + }); } \ No newline at end of file From b64187694b93d78f069d35363f70b056273c74c9 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Fri, 6 May 2022 21:55:16 +0200 Subject: [PATCH 2/3] (#400) Re-export fetchFromUrl as part of the public API --- index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/index.ts b/index.ts index db8b6d43..e0336f23 100644 --- a/index.ts +++ b/index.ts @@ -52,6 +52,7 @@ const loadImage = providerRegistry.getImageReader().load; const saveImage = providerRegistry.getImageWriter().store; const imageResource = (fileName: string) => loadImageResource(providerRegistry, screen.config.resourceDirectory, fileName); +export {fetchFromUrl} from "./lib/imageResources.function"; export { clipboard, From 4dacc37c011d278e1f5fab88812831a3457e5656 Mon Sep 17 00:00:00 2001 From: Simon Hofmann Date: Fri, 6 May 2022 21:58:14 +0200 Subject: [PATCH 3/3] (#400) Added docstring for fetchFromUrl --- lib/imageResources.function.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/imageResources.function.ts b/lib/imageResources.function.ts index 2fc7f04b..6613ec8b 100644 --- a/lib/imageResources.function.ts +++ b/lib/imageResources.function.ts @@ -10,6 +10,11 @@ export function loadImageResource(providerRegistry: ProviderRegistry, resourceDi return providerRegistry.getImageReader().load(fullPath); } +/** + * fetchFromUrl loads remote image content at runtime to provide it for further use in on-screen image search + * @param url The remote URl to fetch an image from as string or {@link URL} + * @throws On malformed URL input or in case of non-image remote content + */ export async function fetchFromUrl(url: string | URL): Promise { let imageUrl: URL; if (url instanceof URL) {