-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Square author photos #530
Comments
Sorry for the delayed response (I've had some life changes to adjust to). You put a lot of thought into this, and I love that! Have you run any quick benchmarking on how long it takes to process an image vs. not processing? |
No problem, this wasn't a super urgent issue haha! I have not, but I can run some tests and get back to you! |
Well I gave benchmarking it a shot, and found the function to execute pretty quickly, but I'd have to assume it would be dependent on the internet connection of the server the app is hosted on. My download speed is pretty good, and all the functions ran pretty fast. Here was my test setup: import sizeOf from 'image-size';
import fetch from 'node-fetch';
import { performance } from 'perf_hooks';
const AUTHOR_IMAGE_URLS = [
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/dcqug62o4s52ubd61ogont4t3l.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/81iHT1SI1lL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/h7fqg9j573mbdr7c8vvuungat2.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/k9gtp50b3kj06bikpg230de34c.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/21pWMFYIf1L.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/bsf846hh2eo2dse1t05c5rmq2e.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/A1QQgrp3VsL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51Uaz1il9IL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/41prWGgXhIL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/312hyoBaIjL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/i1pi9ns4smtfi8o49duan1j2h4.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/9132UvcXnGL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/313l0DRU9VL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/1u8p8qq9fr3eq2ocgma6j56s0g.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/21-OqMcKsAL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/8cigckin175jtpsk3gs361r4ss.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/990aat17klqmn21r86uvo8lb45.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/nn5mlv5h2vfcdbnmm90dtb6ltm.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/u27aie1p3kirmbckb22b7lo63u.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51TEICxU-CL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/h7u6f9a3e680k4dver07t4s0t2.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/ndtsjs1mbus8ubg04hv02g5f3l.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/ppppnrtb11dqtjikkq5carfg90.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/iuibkacc38lubdr0km2akilhe1.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/21dJC-mHlYL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/kps6s9higps8qfj9iaghq872n0.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/71AcCRBHBML.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/96pn5d84f0chcg248pgrp5hel9.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/415Xnu0pwBL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/61w3pqVMCZL.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/u65m852f5j96v6ud70hpfb3hu7.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/rn4hchq6ouadmsu04f1qjs0j3k.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/fkeglaqq0pic05a0v6ieqt4iv5.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/11q81821d0ovjemedg11f7knb8.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/B1PNLDB9k9S.__01_SX120_CR0,0,120,120__.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51rgIda7HDL.__01_SX120_CR0,0,120,120__.jpg',
];
const getSquareImage = async (url) => {
const start = performance.now();
const fullAuthorUrl = url.replace('__01_SX120_CR0,0,120,120__.', '');
const imageRes = await fetch(fullAuthorUrl);
const imgBuffer = await imageRes.buffer();
const imageSize = sizeOf(imgBuffer);
const minDimension = Math.min(imageSize.width, imageSize.height);
const largeSquareImgUrl = url.replace(/120/g, minDimension);
const end = performance.now();
return {
original: url,
full: fullAuthorUrl,
square: largeSquareImgUrl,
time: end - start,
};
};
const getAll = async () => {
const results = await Promise.all(
AUTHOR_IMAGE_URLS.map((url) => getSquareImage(url))
);
console.log(results);
const avgTime =
results.reduce((acc, curr) => acc + curr.time, 0) / results.length;
console.log('average time:', avgTime);
console.log(`for ${results.length} results`);
};
getAll(); And these were my results: [
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/dcqug62o4s52ubd61ogont4t3l.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/dcqug62o4s52ubd61ogont4t3l.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/dcqug62o4s52ubd61ogont4t3l.__01_SX1181_CR0,0,1181,1181__.jpg',
time: 139.79129207134247
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/81iHT1SI1lL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/81iHT1SI1lL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/81iHT1SI1lL.__01_SX464_CR0,0,464,464__.jpg',
time: 138.65283298492432
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/h7fqg9j573mbdr7c8vvuungat2.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/h7fqg9j573mbdr7c8vvuungat2.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/h7fqg9j573mbdr7c8vvuungat2.__01_SX328_CR0,0,328,328__.jpg',
time: 77.4843339920044
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/k9gtp50b3kj06bikpg230de34c.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/k9gtp50b3kj06bikpg230de34c.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/k9gtp50b3kj06bikpg230de34c.__01_SX757_CR0,0,757,757__.jpg',
time: 110.3434579372406
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/21pWMFYIf1L.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/21pWMFYIf1L.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/21pWMFYIf1L.__01_SX229_CR0,0,229,229__.jpg',
time: 77.70391607284546
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/bsf846hh2eo2dse1t05c5rmq2e.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/bsf846hh2eo2dse1t05c5rmq2e.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/bsf846hh2eo2dse1t05c5rmq2e.__01_SX574_CR0,0,574,574__.jpg',
time: 95.5725839138031
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/A1QQgrp3VsL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/A1QQgrp3VsL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/A1QQgrp3VsL.__01_SX1260_CR0,0,1260,1260__.jpg',
time: 145.1996660232544
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/51Uaz1il9IL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/51Uaz1il9IL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/51Uaz1il9IL.__01_SX427_CR0,0,427,427__.jpg',
time: 78.88208293914795
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/41prWGgXhIL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/41prWGgXhIL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/41prWGgXhIL.__01_SX160_CR0,0,160,160__.jpg',
time: 83.80075001716614
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/312hyoBaIjL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/312hyoBaIjL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/312hyoBaIjL.__01_SX207_CR0,0,207,207__.jpg',
time: 81.03462505340576
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/i1pi9ns4smtfi8o49duan1j2h4.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/i1pi9ns4smtfi8o49duan1j2h4.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/i1pi9ns4smtfi8o49duan1j2h4.__01_SX227_CR0,0,227,227__.jpg',
time: 85.4155410528183
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/9132UvcXnGL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/9132UvcXnGL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/9132UvcXnGL.__01_SX1605_CR0,0,1605,1605__.jpg',
time: 126.22391700744629
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/313l0DRU9VL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/313l0DRU9VL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/313l0DRU9VL.__01_SX235_CR0,0,235,235__.jpg',
time: 87.43112504482269
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/1u8p8qq9fr3eq2ocgma6j56s0g.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/1u8p8qq9fr3eq2ocgma6j56s0g.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/1u8p8qq9fr3eq2ocgma6j56s0g.__01_SX208_CR0,0,208,208__.jpg',
time: 86.06299996376038
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/21-OqMcKsAL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/21-OqMcKsAL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/21-OqMcKsAL.__01_SX149_CR0,0,149,149__.jpg',
time: 89.55879199504852
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/8cigckin175jtpsk3gs361r4ss.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/8cigckin175jtpsk3gs361r4ss.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/8cigckin175jtpsk3gs361r4ss.__01_SX957_CR0,0,957,957__.jpg',
time: 94.46991693973541
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/990aat17klqmn21r86uvo8lb45.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/990aat17klqmn21r86uvo8lb45.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/990aat17klqmn21r86uvo8lb45.__01_SX512_CR0,0,512,512__.jpg',
time: 146.34120893478394
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/nn5mlv5h2vfcdbnmm90dtb6ltm.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/nn5mlv5h2vfcdbnmm90dtb6ltm.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/nn5mlv5h2vfcdbnmm90dtb6ltm.__01_SX1880_CR0,0,1880,1880__.jpg',
time: 183.3122079372406
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/u27aie1p3kirmbckb22b7lo63u.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/u27aie1p3kirmbckb22b7lo63u.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/u27aie1p3kirmbckb22b7lo63u.__01_SX260_CR0,0,260,260__.jpg',
time: 94.17554199695587
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/51TEICxU-CL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/51TEICxU-CL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/51TEICxU-CL.__01_SX229_CR0,0,229,229__.jpg',
time: 112.25995790958405
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/h7u6f9a3e680k4dver07t4s0t2.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/h7u6f9a3e680k4dver07t4s0t2.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/h7u6f9a3e680k4dver07t4s0t2.__01_SX2000_CR0,0,2000,2000__.jpg',
time: 269.72129106521606
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/ndtsjs1mbus8ubg04hv02g5f3l.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/ndtsjs1mbus8ubg04hv02g5f3l.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/ndtsjs1mbus8ubg04hv02g5f3l.__01_SX500_CR0,0,500,500__.jpg',
time: 109.27412497997284
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/ppppnrtb11dqtjikkq5carfg90.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/ppppnrtb11dqtjikkq5carfg90.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/ppppnrtb11dqtjikkq5carfg90.__01_SX648_CR0,0,648,648__.jpg',
time: 138.23641693592072
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/iuibkacc38lubdr0km2akilhe1.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/iuibkacc38lubdr0km2akilhe1.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/iuibkacc38lubdr0km2akilhe1.__01_SX2736_CR0,0,2736,2736__.jpg',
time: 177.8967500925064
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/21dJC-mHlYL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/21dJC-mHlYL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/21dJC-mHlYL.__01_SX200_CR0,0,200,200__.jpg',
time: 117.37929105758667
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/kps6s9higps8qfj9iaghq872n0.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/kps6s9higps8qfj9iaghq872n0.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/kps6s9higps8qfj9iaghq872n0.__01_SX300_CR0,0,300,300__.jpg',
time: 122.8955830335617
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/71AcCRBHBML.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/71AcCRBHBML.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/71AcCRBHBML.__01_SX900_CR0,0,900,900__.jpg',
time: 135.1004580259323
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/96pn5d84f0chcg248pgrp5hel9.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/96pn5d84f0chcg248pgrp5hel9.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/96pn5d84f0chcg248pgrp5hel9.__01_SX984_CR0,0,984,984__.jpg',
time: 153.7728750705719
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/415Xnu0pwBL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/415Xnu0pwBL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/415Xnu0pwBL.__01_SX371_CR0,0,371,371__.jpg',
time: 110.14437508583069
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/61w3pqVMCZL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/61w3pqVMCZL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/61w3pqVMCZL.__01_SX547_CR0,0,547,547__.jpg',
time: 139.97262501716614
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/u65m852f5j96v6ud70hpfb3hu7.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/u65m852f5j96v6ud70hpfb3hu7.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/u65m852f5j96v6ud70hpfb3hu7.__01_SX2796_CR0,0,2796,2796__.jpg',
time: 292.4728749990463
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/rn4hchq6ouadmsu04f1qjs0j3k.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/rn4hchq6ouadmsu04f1qjs0j3k.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/rn4hchq6ouadmsu04f1qjs0j3k.__01_SX2078_CR0,0,2078,2078__.jpg',
time: 268.51145792007446
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/fkeglaqq0pic05a0v6ieqt4iv5.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/fkeglaqq0pic05a0v6ieqt4iv5.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/fkeglaqq0pic05a0v6ieqt4iv5.__01_SX768_CR0,0,768,768__.jpg',
time: 127.38229095935822
},
{
original: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/11q81821d0ovjemedg11f7knb8.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/11q81821d0ovjemedg11f7knb8.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/S/amzn-author-media-prod/11q81821d0ovjemedg11f7knb8.__01_SX236_CR0,0,236,236__.jpg',
time: 109.1701248884201
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/B1PNLDB9k9S.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/B1PNLDB9k9S.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/B1PNLDB9k9S.__01_SX4912_CR0,0,4912,4912__.jpg',
time: 263.32591700553894
},
{
original: 'https://images-na.ssl-images-amazon.com/images/I/51rgIda7HDL.__01_SX120_CR0,0,120,120__.jpg',
full: 'https://images-na.ssl-images-amazon.com/images/I/51rgIda7HDL.jpg',
square: 'https://images-na.ssl-images-amazon.com/images/I/51rgIda7HDL.__01_SX315_CR0,0,315,315__.jpg',
time: 146.03679203987122
}
]
average time: 133.7502777212196
for 36 results So an average of 134ms for getting the square image URL. This would always be in addition to the original processing time as you need the original image to be able to determine the square image URL in the first place. I did however notice that there is a weird side case for this. In some cases, Audible appears to not do any cropping for their author images, and has a white border even for the thumbnail image: I am not sure why this is the case but if I had to guess, it seems like it happens when they don't use any facial recognition to find the center of the image. Possibly because they couldn't reliably find a result for that image. This leads to a problem where the large version of that image also has white borders: while the original image without resizing has no borders: At first I thought this was happening specifically in cases where the image was too small but this specific example is massive so I doubt that's it. After checking these 36 example images, I found that 7 of them fell into this category, or just under 20%. This may be enough of an issue to consider this not to be a reliable method, however for many of the examples that did work, the centering is a massive improvement over the automatic centering that Plex does. I'm curious about your thoughts! |
One alternative to adding this directly into Audnexus could be to add it into the Plex agent instead. I actually tried doing that myself before, but Python isn't my best language, and I've been struggling with what's available to use in Plex agents. This was where I started with the from PIL import ImageFile
# ...
class ArtistUpdateTool:
# ...
def get_square_image(self, img_url):
"""
Get square image from Audible
"""
try:
file = urllib.urlopen(img_url)
p = ImageFile.Parser()
while 1:
s = file.read(1024)
if not s:
break
p.feed(s)
file.close()
img_dims = p.close().size
smaller_img_dim = str(min(img_dims))
square_img_url = img_url.replace(
'.jpg',
'.__01_SX'+smaller_img_dim+'_CR0,0'+smaller_img_dim+','+smaller_img_dim+'__.jpg'
)
return square_img_url
except Exception as err:
log.separator(
msg=(
'Error getting square image for ' + self.metadata.title + '\n' + err
),
log_level="error"
)
return img_url
# ...
def parse_api_response(self, response):
"""
Parses keys from API into helper variables if they exist.
"""
if 'description' in response:
self.description = response['description']
if 'genres' in response:
self.genres = response['genres']
if 'name' in response:
self.name = response['name']
if 'image' in response:
self.thumb = self.get_square_image(response['image']) And I got there by following this: https://stackoverflow.com/questions/7460218/get-image-size-without-downloading-it-in-python I'm not sure exactly what went wrong, but I didn't go super far with it. I'm not even sure if Anyway, food for thought! |
Putting this into the agents is the best move since that is where you wanted the centered images to begin with. I know Your Python is quite good, just lacking clearly labeled variables (there's no need to shorten 'dim' or 'img'). |
I might also square images in AudiobookDB because it would be quite useful there. I had a personal loss around when I was nearly 'done' writing the MVP in March, and I could never get it squared up after that. Trying for round 2 this year 😛 |
Haha fair enough, this wasn't really meant to be final code, mostly just what I copied and pasted from stack overflow and tweaked slightly. I more meant that I'm not the best at debugging python code, especially not through an agent running on my Plex server. I tried doing this again using only the jpeg portion of this stackoverflow answer, because that's the only file type Audible returns, but I was still running into issues and wasn't sure how to debug it properly. This one uses only def get_square_image(self, image_url):
"""
Get square image from Audible
"""
try:
file = urllib.urlopen(image_url)
head = file.read(24)
if len(head) != 24:
return
file.seek(0) # Read 0xff next
size = 2
ftype = 0
while not 0xc0 <= ftype <= 0xcf:
file.seek(size, 1)
byte = file.read(1)
while ord(byte) == 0xff:
byte = file.read(1)
ftype = ord(byte)
size = struct.unpack('>H', file.read(2))[0] - 2
# We are at a SOFn block
file.seek(1, 1) # Skip `precision' byte.
height, width = struct.unpack('>HH', file.read(4))
smaller_image_dimension = str(min(height, width))
square_image_url = image_url.replace(
'.jpg',
'.__01_SX'+smaller_image_dimension+'_CR0,0' +
smaller_image_dimension+','+smaller_image_dimension+'__.jpg'
)
return square_image_url
except Exception as err:
log.separator(
msg=(
'Error getting square image for ' + self.metadata.title + '\n' + err
),
log_level="error"
)
return image_url |
No worries! My flow is to:
That being said, there were a couple of issues I patched. Namely exception catching section, since import struct
import urllib
...
class ArtistUpdateTool(UpdateTool):
def get_square_image(self, image_url):
"""
Get square image from Audible
"""
try:
file = urllib.urlopen(image_url)
head = file.read(24)
if len(head) != 24:
return
file.seek(0) # Read 0xff next
size = 2
ftype = 0
while not 0xc0 <= ftype <= 0xcf:
file.seek(size, 1)
byte = file.read(1)
while ord(byte) == 0xff:
byte = file.read(1)
ftype = ord(byte)
size = struct.unpack('>H', file.read(2))[0] - 2
# We are at a SOFn block
file.seek(1, 1) # Skip `precision' byte.
height, width = struct.unpack('>HH', file.read(4))
smaller_image_dimension = str(min(height, width))
square_image_url = image_url.replace(
'.jpg',
'.__01_SX'+smaller_image_dimension+'_CR0,0' +
smaller_image_dimension+','+smaller_image_dimension+'__.jpg'
)
return square_image_url
except Exception as err:
log.separator(
msg=(
'Error getting square image for ' + self.media.title
),
log_level="error"
)
log.error(err)
return image_url
def parse_api_response(self, response):
"""
Parses keys from API into helper variables if they exist.
"""
# Set empty variables
self.date = None
self.genres = None
self.thumb = ''
if 'description' in response:
self.description = response['description']
if 'genres' in response:
self.genres = response['genres']
if 'name' in response:
self.name = response['name']
if 'image' in response:
squared_image = self.get_square_image(response['image'])
log.debug('Here is a square we found: ' + squared_image)
self.thumb = response['image']
Now the error is |
Ah yes, I wasn't sure if that would work for a requested file. So I'd assume to make this work, the requested file would have to be loaded in as a file object. I'm not sure what the best way to do that would be, I guess it could be saved to disk as a temporary file and then loaded in as a file object. Alternatively, it could be possible to do this with file streaming but again, not too familiar with how one might do that in Python haha. I guess I'll look into it using a temp file. Btw, do you know what version of python the Plex agents run on? Is it some version of Python 2? |
They run on Python 2.7. Certain builtins can be imported easily, others have to be added as a library into the project and imported that way. |
So I figured it would be easy enough to just use the Here is what I tried: def get_square_image(self, image_url):
"""
Get square image from Audible
"""
try:
file_name, file_headers = urllib.urlretrieve(image_url)
log.debug('Temp File Name: ' + file_name)
with open(file_name, 'rb') as fhandle:
head = fhandle.read(24)
if len(head) != 24:
return image_url
fhandle.seek(0) # Read 0xff next
size = 2
ftype = 0
while not 0xc0 <= ftype <= 0xcf:
fhandle.seek(size, 1)
byte = fhandle.read(1)
while ord(byte) == 0xff:
byte = fhandle.read(1)
ftype = ord(byte)
size = struct.unpack('>H', fhandle.read(2))[0] - 2
# We are at a SOFn block
fhandle.seek(1, 1) # Skip `precision' byte.
height, width = struct.unpack('>HH', fhandle.read(4))
fhandle.close()
smaller_image_dimension = str(min(height, width))
square_image_url = image_url.replace(
'.jpg',
'.__01_SX'+smaller_image_dimension+'_CR0,0' +
smaller_image_dimension+','+smaller_image_dimension+'__.jpg'
)
return square_image_url
except Exception as err:
log.separator(
msg=(
'Error getting square image for ' + self.media.title
),
log_level="error"
)
log.error(err)
return image_url But now I'm getting the error |
Probably not compiled for their plugin system. We could use their |
Ok, I figured out a way to do it! I ended up using the Here's my final code: import struct
import urllib
import os
# ...
class ArtistUpdateTool:
# ...
def get_square_image(self, image_url):
"""
Get square image from Audible
"""
try:
image_file_dl = urllib.urlopen(image_url)
image_file_dl_contents = image_file_dl.read()
image_file_dl.close()
image_file = os.tmpfile()
image_file.write(image_file_dl_contents)
image_file.seek(0)
head = image_file.read(24)
if len(head) != 24:
image_file.close()
return image_url
image_file.seek(0) # Read 0xff next
size = 2
ftype = 0
while not 0xc0 <= ftype <= 0xcf:
image_file.seek(size, 1)
byte = image_file.read(1)
while ord(byte) == 0xff:
byte = image_file.read(1)
ftype = ord(byte)
size = struct.unpack('>H', image_file.read(2))[0] - 2
# We are at a SOFn block
image_file.seek(1, 1) # Skip `precision' byte.
height, width = struct.unpack('>HH', image_file.read(4))
image_file.close()
smaller_image_dimension = str(min(height, width))
square_image_url = image_url.replace(
'.jpg',
'.__01_SX'+smaller_image_dimension+'_CR0,0,' +
smaller_image_dimension+','+smaller_image_dimension+'__.jpg'
)
return square_image_url
except Exception as err:
log.separator(
msg=(
'Error getting square image for ' + self.media.title
),
log_level="error"
)
log.error(err)
return image_url
def parse_api_response(self, response):
"""
Parses keys from API into helper variables if they exist.
"""
# Set empty variables
self.date = None
self.genres = None
self.thumb = ''
if 'description' in response:
self.description = response['description']
if 'genres' in response:
self.genres = response['genres']
if 'name' in response:
self.name = response['name']
if 'image' in response:
squared_image = self.get_square_image(response['image'])
log.debug('Here is a square we found: ' + squared_image)
self.thumb = squared_image I tried running a full metadata refresh on a test library, and it runs pretty quickly! Now, to my point before about what they look like. Many of the resulting images look much better in my opinion, however for the images that appear to not have facial recognition, it adds a white border like I mentioned before. Here is a comparison, so you can see for yourself: With Square FunctionWithout Square FunctionSo here are my thoughts on the practicality of using this function; Speed wise, I think there is no problem using this method, it seems to run great for me, but you'd have to try it yourself to see if you agree. Visual wise, I think it makes a great improvement to many of the images. For some, it has relatively no impact as their faces are mostly centered anyway, but there are many cases where it does help. I did the results of my relatively small sample size: Out of my 37 authors that the agent was able to find matches/images for:
So overall, the failure rate of this technique is relatively low, but it really depends on how much you dislike the white borders. I think there are two possible ways implementing this could be approached:
Sorry for the long-winded comment, but seeing as this solution doesn't have a 100% success rate, I think it's worth discussing the implementation. If you'd like me to submit a PR to that repo with the new custom agent option, I'd be happy to do so! And I can also look into how to make the agent add both images to the artists if that's something you'd be interested in. |
This is excellent! An option for squared photos would be the best approach, and on a complexity scale, relatively easy to implement. It's also easy to add both images. I wish there were a way to determine when a 'white border' picture was used because those don't look great. However, the payoff of centered photos is higher than the inconvenience of a low percentage of them. |
I agree that this would be an ideal solution, especially if you know how to add both! Would you like me to submit the start of a PR with a new option implemented? You're welcome to take this code and do it yourself, but I also have no issue doing it! If you already know how to add both images to the profile, then I'd be cool letting you handle that in post, but I could easily implement the option part first if you'd like!
I do agree that it's worth it personally. But you're right, it would be great if there was a way to identify them. I actually thought about this for a bit, but I couldn't come up with anything that didn't involve some form of image processing. The strange thing is, when it does return the bordered images, they also appear that way in Audible, even though they're tiny thumbnails. That would definitely imply to me that they don't know where to center the images. Overall, the whole author image thing is relatively new to Audible anyway, so I'm sure they're still working out the kinks. The one approach I can think of would be to use an image processing package like |
Yes, feel free to open a PR (target |
Quick question about your |
As we speak, I am working on the latest |
I see the problem with the server EDIT: #485 (comment) |
This is what I'm getting from a refresh on an author with one book:
|
Please read the uptime status. I've shut down the servers until I have time to migrate them to a non-shit host |
Which uptime status are you referring to? EDIT: nevermind I found it |
Oh wow, I hate to admit this, but I was completely wrong about what's happening with the white space. Not only that but I was wrong about how the images were centered 🤦 I was searching for a pattern in the images to see if I could find a reason why some of them didn't work properly, and finally I realized that they were all landscape images. Which then made me look at the URL pattern again.
I realized the https://images-na.ssl-images-amazon.com/images/I/21dJC-mHlYL.__01_SY200_CR0,0,200,200__.jpg This then made me realize that the image was just getting centered on the left size... so I checked the portrait images... and I realized there is no intelligent centering on them whatsoever, they're just being cropped to the top of the image. I feel quite dumb for not realizing this sooner. I don't think all of this work was for nothing, however. Through this, I realized that most of Audible's author images that are in portrait mode are much better off being centered at the top of the image. Enough so that I thought they were using object recognition to determine the center point haha. So I still think there is some merit to this functionality, however I think it should only be applied to portrait images. I think the best use case for this would be to check if the width is smaller, and if it is, center the author image at the top. If the height is smaller, I think it's better off just being horizontally centered. This could either be done with some simple math, or by just returning the original image URL you already have and let Plex handle the centering, which is probably the better solution. I'm curious on your thoughts, or if you think there even needs to be an option for this anymore. I feel like the vertical centering could probably just be on by default, as that's the way Audible handles their Author images already. I honestly find it strange that they don't handle their landscape images in the same way, it's pretty odd looking when they have the white borders only on landscape images. Also, sorry for misleading you here, I went way too deep down the wrong rabbit hole haha 😅 |
Closed since this was merged on the client side. Great work as always Chris! |
One feature that could be nice to add to this package, would be returning a square version of an author's photo in addition to the full sized one. The main benefit I can see for this is the Plex agent that was written for this package. When a non-square image is used for an artist photo in Plex, it is always cropped at the center, whereas by default the Audible author images are centered on their faces. And because there are no standards for the shape of the Audible author images, they always look inconsistent in Plex.
Plex:
Audible:
I assume Audible locates the face using Amazon Rekognition or something of the sort.
By default, the Audible author images are only thumbnails, which are obviously too low in resolution to be useful. However, if you know the dimensions of the raw image you generate a square image from, it's possible to generate a facially centered square image by modifying the initial image URL.
By default, the Author images come in the following format:
And from looking at your code, I know you remove the
__01_SX120_CR0,0,120,120__.
part to get the URL for the full sized image, which looks something like this:Now, I'm not sure if you've tried messing with their initial URL format, but if you just increase all the numbers to some arbitrarily high resolution number, borders will be added to fill in the extra space if the image isn't large enough to accommodate:
However, I have found that if you pull in the image and find the smaller dimension (usually the width but sometimes the photos are in landscape), and replace all the
120
values in the original thumbnail URL with that number, you'll get the largest image size available while still being a square image centered on the author's face. Taking this image for example, the width of the full size image is464
(still pretty small but much bigger than120
), and the modified original URL would look like this:Which is much more useful for something like Plex! The best part is, you don't have to do any subject identification on the photo itself because Amazon has already done the work for you. Plus, this whole process can be scripted pretty easily in Node:
Idk if this is outside the scope of what you intend to deliver with this project, but it's something worth thinking about! I think it would be a great alternative to using the full size image for Plex thumbnails.
The only issue with this process is that you'd have to load a lot of images into memory to check their dimensions, which would probably affect processing time/power. I'm not sure how that would ultimately affect the performance of this tool, but I think it's worth investigating.
The text was updated successfully, but these errors were encountered: