diff --git a/api/assetImage.js b/api/assetImage.js
index 69aaa51..cf9d82d 100644
--- a/api/assetImage.js
+++ b/api/assetImage.js
@@ -7,6 +7,10 @@
* a bit slow, and consume significant RAM. So, caching is going to be
* important, so that we're not calling this all the time and overloading the
* endpoint!
+ *
+ * Parameters:
+ * - libraryUrl: A https://images.neopets.com/ URL to a JS movie library
+ * - size: 600, 300, or 150. Determines the output image size.
*/
const beeline = require("honeycomb-beeline")({
writeKey: process.env["HONEYCOMB_WRITE_KEY"],
@@ -53,7 +57,7 @@ async function getBrowser() {
}
async function handle(req, res) {
- const { libraryUrl } = req.query;
+ const { libraryUrl, size } = req.query;
if (!libraryUrl) {
return reject(res, "libraryUrl is required");
}
@@ -65,9 +69,13 @@ async function handle(req, res) {
);
}
+ if (size !== "600" && size !== "300" && size !== "150") {
+ return reject(res, `size must be 600, 300, or 150, but was: ${size}`);
+ }
+
let imageBuffer;
try {
- imageBuffer = await loadAndScreenshotImage(libraryUrl);
+ imageBuffer = await loadAndScreenshotImage(libraryUrl, size);
} catch (e) {
console.error(e);
return reject(res, `Could not load image: ${e.message}`, 500);
@@ -82,9 +90,12 @@ async function handle(req, res) {
return res.send(imageBuffer);
}
-async function loadAndScreenshotImage(libraryUrl) {
+async function loadAndScreenshotImage(libraryUrl, size) {
const assetImagePageUrl = new URL(ASSET_IMAGE_PAGE_BASE_URL);
- assetImagePageUrl.search = new URLSearchParams({ libraryUrl }).toString();
+ assetImagePageUrl.search = new URLSearchParams({
+ libraryUrl,
+ size,
+ }).toString();
console.debug("Opening browser page");
const browser = await getBrowser();
diff --git a/src/app/InternalAssetImagePage.js b/src/app/InternalAssetImagePage.js
index 2d3aa1b..c9db2b8 100644
--- a/src/app/InternalAssetImagePage.js
+++ b/src/app/InternalAssetImagePage.js
@@ -39,6 +39,7 @@ function InternalAssetImagePageContent() {
const location = useLocation();
const search = new URLSearchParams(location.search);
const libraryUrl = search.get("libraryUrl");
+ const size = search.get("size") || "600";
const [movieError, setMovieError] = React.useState(null);
@@ -64,6 +65,14 @@ function InternalAssetImagePageContent() {
);
}
+ if (size !== "600" && size !== "300" && size !== "150") {
+ return (
+
+ Error: size must be 600, 300, or 150, but was: {size}
+
+ );
+ }
+
if (movieError) {
return (
@@ -73,11 +82,17 @@ function InternalAssetImagePageContent() {
}
return (
-
+
{
const layer = await swfAssetLoader.load(id);
- // For the largest size, try to use the official Neopets PNG!
- //
- // NOTE: This is mainly to avoid cases where the official PNG, based on
- // the official SWF, is inaccurate. (This was the case for the
- // Flying in an Airplane item when it first released, with the
- // OFFICIAL_SVG_IS_INCORRECT glitch.)
- //
- // TODO: This doesn't really help us with the glitches in our own PNGs,
- // because 1) if an official PNG is available, an official SVG
- // probably is too, and we prefer to use that in most cases; and 2)
- // outfit image thumbnails currently only request 300x300 at most,
- // so we'll still use our own PNGs for those cases.
- if (size === "SIZE_600") {
- const {
- format,
- jsAssetUrl,
- pngAssetUrl,
- } = await loadAndCacheAssetDataFromManifest(db, layer);
+ const {
+ format,
+ jsAssetUrl,
+ pngAssetUrl,
+ } = await loadAndCacheAssetDataFromManifest(db, layer);
+ // For the largest size, try to use the official Neopets PNG!
+ // TODO: Offer an API endpoint to resize the official Neopets PNG maybe?
+ // That'll be an important final step before turning off the
+ // Classic DTI image converters.
+ if (size === "SIZE_600") {
// If there's an official single-image PNG we can use, use it! This is
// what the official /customise editor uses at time of writing.
if (format === "lod" && !jsAssetUrl && pngAssetUrl) {
return pngAssetUrl.toString();
}
+ }
- // Or, if this is a movie, we can generate the PNG ourselves.
- // TODO: Support this for smaller image sizes, too.
- if (format === "lod" && jsAssetUrl) {
- const httpsJsAssetUrl = jsAssetUrl
- .toString()
- .replace(/^http:\/\//, "https://");
- return (
- `https://impress-2020.openneo.net/api/assetImage` +
- `?libraryUrl=${encodeURIComponent(httpsJsAssetUrl)}`
- );
- }
+ // Or, if this is a movie, we can generate the PNG ourselves.
+ if (format === "lod" && jsAssetUrl) {
+ const httpsJsAssetUrl = jsAssetUrl
+ .toString()
+ .replace(/^http:\/\//, "https://");
+ const sizeNum = size.split("_")[1];
+ return (
+ `https://impress-2020.openneo.net/api/assetImage` +
+ `?libraryUrl=${encodeURIComponent(httpsJsAssetUrl)}&size=${sizeNum}`
+ );
}
// Otherwise, fall back to the Classic DTI image storage, which is