Miscellaneous IMG related utilities
// ==UserScript==
// @name MISC Image Utilities
// @namespace https://github.com/w4tchdoge
// @version 3.5.4-20250207_193332
// @description Miscellaneous IMG related utilities
// @author w4tchdoge
// @homepage https://github.com/w4tchdoge/MISC-UserScripts
// @match *://cdn.discordapp.com/*
// @match *://media.discordapp.net/*
// @match *://pbs.twimg.com/media/*
// @match *://preview.redd.it/*
// @grant GM_registerMenuCommand
// @grant GM.registerMenuCommand
// @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// @license AGPL-3.0-or-later
// @history 3.5.4 — Switch the order of Discord search params that get added to the new URL so that my ones can override any existing ones
// @history 3.5.3 — Make Discord IMG fix compatible with the "new" Discord IMG search params
// @history 3.5.2 — Fix issue when encountering preview.redd.it image URLs with the post title in the URL pathname
// @history 3.5.1 — Hard-disable script autorunning on Discord attachments
// @history 3.5.0 — Overhaul script to use URL() function/method for parsing and making URLs
// @history 3.4.0 — Added support for Discord banner images
// ==/UserScript==
/* SCRIPT GOES FUCKY WUCKY IF YOU SET THIS TO TRUE, EXCEPT NOT ANYMORE XD */
const discord_autofix = true;
const twitter_autofix = false;
const ireddit_autofix = true;
const currPG_URL = new URL(window.location.href);
function generic_Discord_IMG_Fix(x) {
const init_url = new URL(window.location);
let file_extension;
if (Boolean(x)) {
file_extension = x;
} else {
file_extension = init_url.pathname.split('.').at(1).toString();
}
const usr_search_params = {
size: `4096`,
quality: `lossless`
};
const search_params = (() => {
let output_search_params = new URLSearchParams();
const init_search_params = Object.fromEntries(init_url.searchParams.entries());
Object.entries(init_search_params).forEach(
([k, v]) => {
output_search_params.set(k, v);
}
);
Object.entries(usr_search_params).forEach(
([k, v]) => {
output_search_params.set(k, v);
}
);
return output_search_params.toString();
})();
const new_url = new URL(`${init_url.pathname.split('.').at(0)}.${file_extension}?${search_params}`, `https://${init_url.hostname}`);
return new_url;
}
if (currPG_URL.hostname.includes(`discordapp`)) {
function Discord_IMG_Fix(override) {
var new_url;
if (currPG_URL.pathname.includes(`.webp`) || Boolean(override)) {
new_url = generic_Discord_IMG_Fix(`png`);
} else {
new_url = generic_Discord_IMG_Fix();
}
// console.log(new_url.toString());
window.location.href = new_url;
}
function DIF_override() {
Discord_IMG_Fix(`override`);
}
GM.registerMenuCommand(`Discord – Image → PNG`, DIF_override);
GM.registerMenuCommand(`Discord – Lossless Image`, Discord_IMG_Fix);
if (discord_autofix === true && !currPG_URL.pathname.includes(`/attachments/`) && currPG_URL.pathname.includes(`webp`) && currPG_URL.searchParams.has(`quality`) === false) {
Discord_IMG_Fix();
}
if (discord_autofix === true && !currPG_URL.pathname.includes(`/attachments/`) && (currPG_URL.searchParams.has(`quality`) === false || currPG_URL.searchParams.has(`size`) === false)) {
Discord_IMG_Fix();
}
}
if (currPG_URL.hostname.includes(`twimg`)) {
function Twitter_Image2PNG() {
var init_url = new URL(window.location.href);
var new_url = new URL(`https://pbs.twimg.com`);
new_url.pathname = init_url.pathname.split('.')[0];
var search_params = {
format: `png`,
name: `4096x4096`
};
Object.entries(search_params).forEach(
([k, v]) => {
new_url.searchParams.append(k, v);
}
);
window.location.href = new_url;
}
GM.registerMenuCommand(`Twitter – Image → PNG`, Twitter_Image2PNG);
if (twitter_autofix === true && currPG_URL.search.includes(`4096x4096`) === false) {
Twitter_Image2PNG();
}
}
if (currPG_URL.hostname == `preview.redd.it`) {
function i_redd_it_FixPreview() {
const init_url = window.location;
if (ireddit_autofix == true) {
window.stop();
}
// Extract just the filename from the path of a URL like https://preview.redd.it/gen-z-deciding-who-serves-and-who-protects-v0-117e4bxr7bce1.jpeg
const new_path = init_url.pathname.split(`/`).slice(-1).toString().split(/[\(\)_-]/).at(-1);
const new_url = new URL(new_path, `https://i.redd.it`);
if (ireddit_autofix == true) {
window.location.replace(new_url);
} else {
window.location.href = new_url;
}
}
GM.registerMenuCommand(`Reddit – preview.redd.it → i.redd.it`, i_redd_it_FixPreview);
if (ireddit_autofix === true) {
i_redd_it_FixPreview();
}
}