is there an addon to rip content protected images? Topic is solved

Add-ons for Pale Moon and other applications
General discussion, compatibility, contributed extensions, themes, plugins, and more.

Moderators: FranklinDM, Lootyhoof

User avatar
Moonchild
Project founder
Project founder
Posts: 39633
Joined: 2011-08-28, 17:27
Location: Sweden

Re: is there an addon to rip content protected images?

Post by Moonchild » 2026-06-17, 03:54

joshex wrote:
2026-06-16, 22:41
the character fullsize images don't provide a rightclick save image as option. I even tried removing the overlay, still no right click save as.

not sure how you're grabbing them.
Ah I didn't try to grab the transparent character images. You didn't specify exactly what you were trying to grab, so I assumed they'd be the "scenic" displays. But, considering you've managed to get what you were trying to do (and indeed none of it is actually protected media there) I'm considering this solved.
"Sales hates anything that can't be turned into a confident sentence." - anonymous warehouse worker
"Why debate someone you fundamentally don't trust?" - Dario Amodei
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

User avatar
joshex
Hobby Astronomer
Hobby Astronomer
Posts: 25
Joined: 2025-12-17, 00:31

Re: is there an addon to rip content protected images?

Post by joshex » 2026-06-17, 13:48

Moonchild wrote:
2026-06-17, 03:54
joshex wrote:
2026-06-16, 22:41
the character fullsize images don't provide a rightclick save image as option. I even tried removing the overlay, still no right click save as.

not sure how you're grabbing them.
Ah I didn't try to grab the transparent character images. You didn't specify exactly what you were trying to grab, so I assumed they'd be the "scenic" displays. But, considering you've managed to get what you were trying to do (and indeed none of it is actually protected media there) I'm considering this solved.
yep, though they are content protected, but some lower-moderate level hacking can get them. but they designed them to not be able to be gotten.

Kris_88
Board Warrior
Board Warrior
Posts: 1195
Joined: 2021-01-26, 11:18

Re: is there an addon to rip content protected images?

Post by Kris_88 » 2026-06-18, 14:30

joshex wrote:
2026-06-17, 13:48
yep, though they are content protected, but some lower-moderate level hacking can get them. but they designed them to not be able to be gotten.
There's a "clean" method, without any hacking. Open the context menu in a blank space on the page and select "View Page Info." In the dialog that opens, select the "Media" tab. Study this dialog carefully; for example, you can add a column with image sizes and sort by size. You can also save any image, including character images with transparent backgrounds (they save perfectly).

User avatar
joshex
Hobby Astronomer
Hobby Astronomer
Posts: 25
Joined: 2025-12-17, 00:31

Re: is there an addon to rip content protected images?

Post by joshex » 2026-06-20, 13:12

Kris_88 wrote:
2026-06-18, 14:30
joshex wrote:
2026-06-17, 13:48
yep, though they are content protected, but some lower-moderate level hacking can get them. but they designed them to not be able to be gotten.
There's a "clean" method, without any hacking. Open the context menu in a blank space on the page and select "View Page Info." In the dialog that opens, select the "Media" tab. Study this dialog carefully; for example, you can add a column with image sizes and sort by size. You can also save any image, including character images with transparent backgrounds (they save perfectly).
the character images do not show up in that list. that's why I said they are content protected. they are designed to appear but not appear in url/media lists. so a tiny bit of hacking is needed to get them.

Kris_88
Board Warrior
Board Warrior
Posts: 1195
Joined: 2021-01-26, 11:18

Re: is there an addon to rip content protected images?

Post by Kris_88 » 2026-06-20, 18:04

joshex wrote:
2026-06-20, 13:12
the character images do not show up in that list.
Indeed, not in all cases.
However, if you view the image using the gallery (from the game's main menu, "HEROES" -> "GALLERY"), the image of the selected hero appears in the "Page Info" section.

In other cases, you can track the download of the desired image via Tools -> Developer Tools -> Network.

As for your initial question about the add-on, I'm afraid there's no universal solution...

User avatar
joshex
Hobby Astronomer
Hobby Astronomer
Posts: 25
Joined: 2025-12-17, 00:31

Re: is there an addon to rip content protected images?

Post by joshex » 2026-06-22, 01:22

Kris_88 wrote:
2026-06-20, 18:04
joshex wrote:
2026-06-20, 13:12
the character images do not show up in that list.
Indeed, not in all cases.
However, if you view the image using the gallery (from the game's main menu, "HEROES" -> "GALLERY"), the image of the selected hero appears in the "Page Info" section.

In other cases, you can track the download of the desired image via Tools -> Developer Tools -> Network.

As for your initial question about the add-on, I'm afraid there's no universal solution...
yeah, no one stop ripper. anyways I found alot of other images in Inspector under Sources, even the variants of the animated stuff is there (albeit as body parts; "some assembly required") I understand they're using webgl polygons to take parts of said images and move them to appear animated. tempted to rip those plop them on polygons in blender and render animations. but I'm really far too lazy to mess with someone else's work to that extent. that's a whole different topic. but yeah, now I know methods to get "content protected" content from sites. yay. it really is different from the old days where everything was a url fragment in page source, they've gone to great lengths to hide stuff from simple resource grabbers.

User avatar
tellu-white
Lunatic
Lunatic
Posts: 351
Joined: 2022-03-08, 22:02
Location: Arad, Romania

Re: is there an addon to rip content protected images?

Post by tellu-white » 2026-06-25, 15:59

For those who want to save images from "Google Arts & Culture" ( https://artsandculture.google.com/asset/napoleon-crossing-the-alps-paul-delaroche/cwF8_mSi8tlbXw ) to their hard drive, I'm posting an update to the Custom Button code from my previous post. The new code takes a screenshot of the Full Image after this has been created in a new TAB by mixing the Partial Images.

In this new version, I've removed the Partial Image "width variable" (which, in the old version, had to be adjusted on a case-by-case basis). Also, I've improved the code that retrieves from the page the parameters of the Partial Images with "blob" URLs, and I've also changed how they're grabbed: by pressing "Ctrl + Alt + Shift" + Click on each new Partial Image that becomes visible after each new scroll.

Code: Select all


/* Initialization Code */

/*	HELP:

	1. "Ctrl + Alt + Shift" + "Click on Partial Image"  = Save the parameters of Partial Image TAGs with "blob" URLs to a variable ( "array" ).
	
		IMPORTANT: The step above must be repeated for each new Partial Image obtained by scrolling the previous Partial Image, until every portion of the Full Image is displayed in the browser's window.

	2. "Ctrl" + "Click on BUTTON" 				= Display in a new TAB the Full Image created from all the Partial Images ( which were obtained using XMLHttpRequest ) and Take Screenshot of Full Image.
	
		IMPORTANT: This mix of Partial Images is saved to disk as a Single File containing the Full Image.

	3. "Shift" + "Click on BUTTON" 				= Reset the Button Before Using it Again -> Only if the previous use of this Custom Button was not ( successfully ) completed ( by pressing "Ctrl + Click on BUTTON" ).
*/

var prompts__for_save_blob_images = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);

var arr_blob_images_parameters = [];
var arr_blob_images_parameters__unique_blob_URL__sorted = [];
var index_arr_blob_images_parameters__unique_blob_URL__sorted = 0;
var arr_blob_Images_in_base64_Format = [];

function get_transform_translate3d_values(el){
	var values = el.style.transform.split(/\w+\(|\);?/);
	
	if( !values[1] || !values[1].length ){
		return [];
	}
	
	return values[1].split(/,\s?/g);
}

function get_a_Multidimensional_Array_with_unique_blob_URL(input_multidimensional_array, specified_inner_arrays_index){
	var number_of_inner_array_indexes = input_multidimensional_array[0].length - 1;	
	var arr_dummy = [];
	
	for( var k = 0; k <= number_of_inner_array_indexes; k++ ){
		arr_dummy.push("dummy");
	}
	
	input_multidimensional_array.push(arr_dummy);
	
	var temp__arr_with_unique_elements_at_a_specified_inner_arrays_index = [];
	var index = 0;

	var arr_with_unique_elements_at_a_specified_inner_arrays_index = input_multidimensional_array.reduce(function (accumulator, currentValue){
		var temp_array = [];
		
		for( var i = 0; i <= number_of_inner_array_indexes; i++ ){
			if(i != specified_inner_arrays_index){
				var temp_element = currentValue[i];
				temp_array.push(temp_element);
				
			} else if(i == specified_inner_arrays_index){
				var temp_element = currentValue[specified_inner_arrays_index];
				temp_array.push(temp_element);
			}
		}
		
		if(accumulator.indexOf(currentValue[specified_inner_arrays_index]) == -1){
			temp__arr_with_unique_elements_at_a_specified_inner_arrays_index.push(temp_array);
			accumulator.push(currentValue[specified_inner_arrays_index]);
			
			if(index == input_multidimensional_array.length - 1){
				accumulator = temp__arr_with_unique_elements_at_a_specified_inner_arrays_index.slice(0, temp__arr_with_unique_elements_at_a_specified_inner_arrays_index.length - 1);
			}
		}
		
		index++;
		
		return accumulator;
	  
	}, []);

	return arr_with_unique_elements_at_a_specified_inner_arrays_index;
}

function get_from_page_all_parameters_of_visible_blob_images(arr_images){
	for(var i=0; i<arr_images.length; i++){
		var image = arr_images[i];
		
		if(image.style.transform.includes("translate3d")){
			var img_URL = image.src;
			
			var img_height;
			var img_width;
			var img_tag_BoundingClientRect = image.getBoundingClientRect();
			
			if(image.height){
				img_height = parseInt(image.height);
				
			} else{
				img_height = parseInt(img_tag_BoundingClientRect.height);
			}
			
			if(image.width){
				img_width = parseInt(image.width);
				
			} else{
				img_width = parseInt(img_tag_BoundingClientRect.width);
			}
			
			var int_tx;
			var int_ty;
		
			var arr_translate3d_values = get_transform_translate3d_values(image);

			if( !arr_translate3d_values.length == 0 ){
				var regEx = /(-*[\d\.]*)/;	
				
				if(arr_translate3d_values[0]){
					var str_tx = arr_translate3d_values[0].match(regEx);

					if(str_tx){
						int_tx = parseInt(str_tx);
					}
				}

				if(arr_translate3d_values[1]){
					var str_ty = arr_translate3d_values[1].match(regEx);

					if(str_ty){
						int_ty = parseInt(str_ty);
					}
				}
				
			} else{
				continue;
			}
			
			var arr_temp = [int_ty, int_tx, img_height, img_width, img_URL];
			arr_blob_images_parameters.push(arr_temp);
			
			if(i == arr_images.length - 1){
				if(arr_blob_images_parameters.length > 0){
					prompts__for_save_blob_images.alert(null, 'Save Partial Images Parameters to Array', 'Saving Partial Image Parameters to Array is Complete');
				
				} else{
					prompts__for_save_blob_images.alert(null, '"translate3d" ERROR', '"Images do not includes "translate3d" or "translate3d" returns ERROR');
				}
			}
			
		} else{
			continue;
		}
	}
}

function get_blob_images_in_base64_format(){
	var arr_length = arr_blob_images_parameters__unique_blob_URL__sorted.length;
	
	if(index_arr_blob_images_parameters__unique_blob_URL__sorted < arr_length){
		var arr_image_parameters = arr_blob_images_parameters__unique_blob_URL__sorted[index_arr_blob_images_parameters__unique_blob_URL__sorted];
		var img_URL = arr_image_parameters[4];
		
		get_image_in_blob_format_with_XMLHttpRequest(img_URL);
		
	} else if(index_arr_blob_images_parameters__unique_blob_URL__sorted == arr_length){
		create_full_image_from_partial_images_in__new_tab();
	}
}

function get_image_in_blob_format_with_XMLHttpRequest(img_URL) {
	var xhr = new XMLHttpRequest();

	xhr.onreadystatechange = function() {
		if(this.readyState == 4 && this.status == 200){
			var img_blob;

			(async () => {
				var iterationCount = 0;
				
				do {
					img_blob = xhr.response;
					
					if(img_blob){
						var contentType = xhr.getResponseHeader('Content-Type');
						get_base64_image_from_image_blob_format_and_save_base64_to_array(img_blob, contentType);
						
						break;
					}
					
					if(iterationCount == 5){
						index_arr_blob_images_parameters__unique_blob_URL__sorted = index_arr_blob_images_parameters__unique_blob_URL__sorted + 1;
						get_blob_images_in_base64_format();
					}
					
				} while (await new Promise(resolve => setTimeout(() => resolve(iterationCount++), 1000)) < 5);
			})();
		}
	};

	xhr.open("GET", img_URL, true);
	xhr.responseType = "blob";
	xhr.send();
}

function get_base64_image_from_image_blob_format_and_save_base64_to_array(img_blob, contentType) {
	try{
		var blobToBase64 = function(blob, cb) {
			var reader = new FileReader();
			
			reader.onload = function() {
				var dataUrl = reader.result;
				var base64 = dataUrl.split(',')[1];
				cb(base64);
			}
			
			reader.readAsDataURL(blob);
		};
		
		blobToBase64(img_blob, function(base64) {
			var base64_Image = "data:" + contentType + ";base64," + base64;
			
			var arr_image_parameters = arr_blob_images_parameters__unique_blob_URL__sorted[index_arr_blob_images_parameters__unique_blob_URL__sorted];
			var int_ty = arr_image_parameters[0];
			var int_tx = arr_image_parameters[1];
			var img_height = arr_image_parameters[2];
			var img_width = arr_image_parameters[3];
			var img_URL = base64_Image;
			
			var arr_temp = [int_ty, int_tx, img_height, img_width, img_URL];
			arr_blob_Images_in_base64_Format.push(arr_temp);
			
			index_arr_blob_images_parameters__unique_blob_URL__sorted = index_arr_blob_images_parameters__unique_blob_URL__sorted + 1;			
			get_blob_images_in_base64_format();
		});
		
	} catch(err){
		// console.log("ERROR : ",  err.message);
	}
}

function create_full_image_from_partial_images_in__new_tab(){
	var html = '<html><head><meta charset="utf-8"></head><body></body></html>';
	var page_URL = "data:text/html," + encodeURIComponent(html);

	var final_position = gBrowser.tabContainer.selectedIndex + 1;
	var new_tab = gBrowser.addTab(page_URL);
	gBrowser.moveTabTo(new_tab, final_position);
	gBrowser.selectedTab = new_tab;

	setTimeout(function() {
		try{
			var body = content.document.getElementsByTagName("body")[0];
			
			var arr_row_width = [];
			var int_row_width = 0;
			var previous_int_ty = arr_blob_Images_in_base64_Format[0][0];

			for(var i=0; i<arr_blob_Images_in_base64_Format.length; i++){
				var current_int_ty = arr_blob_Images_in_base64_Format[i][0];
				var current_width = arr_blob_Images_in_base64_Format[i][3];
				var current_height = arr_blob_Images_in_base64_Format[i][2];
				
				if(current_int_ty == previous_int_ty){
					int_row_width = int_row_width + current_width;
				}
				
				if(current_int_ty != previous_int_ty){
					previous_int_ty = current_int_ty;
					
					arr_row_width.push(int_row_width);
					int_row_width = current_width;
				}
				
				var img_tag = content.document.createElement("img");
				img_tag.src = arr_blob_Images_in_base64_Format[i][4];
				img_tag.style.cssText = 'width: ' + current_width + 'px !important; min-width: ' + current_width + 'px !important; height: ' + current_height + 'px !important; min-height: ' + current_height + 'px !important;';
				
				body.appendChild(img_tag);
				
				if(i == arr_blob_Images_in_base64_Format.length - 1){
					// Sort "arr_row_width" in descending order

					var arr_row_width__sorted = arr_row_width.sort( function (a,b) {
						if (a[0] > b[0]) return -1;
						if (a[0] < b[0]) return  1;
						
						return 0;
					});
					
					var page_width = arr_row_width__sorted[0];
					
					setTimeout(function() {
						var final_body = content.document.getElementsByTagName("body")[0];
						final_body.style.cssText = "width: " + page_width + "px; margin: 0px; padding: 0px;";
						
						arr_row_width.length = 0;
						arr_blob_Images_in_base64_Format.length = 0;
						arr_blob_images_parameters__unique_blob_URL__sorted.length = 0;
						arr_blob_images_parameters.length = 0;
						index_arr_blob_images_parameters__unique_blob_URL__sorted = 0;
						
						setTimeout(function() {
							take_Screenshot_of_Full_blob_Image(true);
							
						}, 1000);
						
					}, 500);
				}
			}
			
		} catch(err){
			// console.log("ERROR : ",  err.message);
		}
		
	}, 1000);
}

function take_Screenshot_of_Full_blob_Image(all){
	var win = content, doc = win.document, docEle = (doc.compatMode == "CSS1Compat") ? doc.documentElement : doc.body;
	var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
	canvas.width = Math.min((all && docEle.scrollWidth > docEle.clientWidth) ? docEle.scrollWidth : docEle.clientWidth, 32000);
	canvas.height = Math.min((all && docEle.scrollHeight > docEle.clientHeight) ? docEle.scrollHeight : docEle.clientHeight, 32000);
	var context = canvas.getContext("2d");
	context.drawWindow(win, all ? 0 : win.pageXOffset, all ? 0 : win.pageYOffset, canvas.width, canvas.height, "white");
	var uri = makeURI(canvas.toDataURL("image/png"));

	var new_date = new Date();
	var year_month_date = new_date.getFullYear() + "." + ("0"+(new_date.getMonth()+1)).slice(-2) +"."+("0" + new_date.getDate()).slice(-2);
	var new_now = year_month_date + " - " + new_date.toLocaleFormat("%H.%M.%S");

	var fileName = "Screenshot - " + new_now;

	var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(Components.interfaces.nsIFilePicker);
	fp.init(window, "Save Screenshot As", fp.modeSave);
	fp.appendFilter("", "*.png");
	fp.appendFilters(fp.filterImages | fp.filterAll);
	fp.defaultExtension = "png";
	fp.defaultString = fileName + ".png";
	if (fp.show() == fp.returnCancel || !fp.file) return;

	Components.classes['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'].createInstance(Components.interfaces.nsIWebBrowserPersist).saveURI(uri, null, null, null, null, null, fp.file, null);
}

this.buttonClick___Save_to_File_in_base64_Format_blob_Images = function(event){
	if(event.button == 0){
		
		// "Ctrl" + "Click on BUTTON" = Display in a new TAB the Full Image created from all the Partial Images ( which were obtained using XMLHttpRequest )
		
		if(event.ctrlKey && !event.altKey && !event.shiftKey){
			// Sort by width and by height in descending order

			var arr_blob_images_parameters__sorted = arr_blob_images_parameters.sort( function (a,b) {
				if (a[3] > b[3]) return -1;
				if (a[3] < b[3]) return  1;
				if (a[2] > b[2]) return -1;
				if (a[2] < b[2]) return  1;
				
				return 0;
			});
			
			var blob_URL_index = 4;
			var arr_blob_images_parameters__unique_blob_URL = get_a_Multidimensional_Array_with_unique_blob_URL(arr_blob_images_parameters__sorted, blob_URL_index);

			// Sort by int_ty ... in ascending order
			
			arr_blob_images_parameters__unique_blob_URL__sorted = arr_blob_images_parameters__unique_blob_URL.sort( function (a,b) {
				if (a[0] > b[0]) return  1;
				if (a[0] < b[0]) return -1;
				if (a[1] > b[1]) return  1;
				if (a[1] < b[1]) return -1;
				if (a[2] > b[2]) return  1;
				if (a[2] < b[2]) return -1;
				if (a[3] > b[3]) return  1;
				if (a[3] < b[3]) return -1;
				
				return 0;
			});
			
			get_blob_images_in_base64_format();
		}
		
		// "Shift" + "Click on BUTTON" = Reset the Button Before Using it Again
		
		else if(event.shiftKey && !event.ctrlKey && !event.altKey){
			arr_blob_Images_in_base64_Format.length = 0;
			arr_blob_images_parameters__unique_blob_URL__sorted.length = 0;
			arr_blob_images_parameters.length = 0;
			index_arr_blob_images_parameters__unique_blob_URL__sorted = 0;
			
			prompts__for_save_blob_images.alert(null, 'Reset the Button', 'Resetting the Button Before Using it Again is Complete');
		}
	}
}

this.setAttribute("onclick", "this.buttonClick___Save_to_File_in_base64_Format_blob_Images(event)");

// "Ctrl + Alt + Shift" + "Click on IMAGE" = Save the parameters of Partial Image TAGs with "blob" URLs to a variable

var get_element_containing_blob_image_tags = {
    handleEvent: function(event) {
		if (event.button == 0 && event.ctrlKey && event.altKey && event.shiftKey){
			var target = event.target
			
			do {
				var target_innerHTML = target.innerHTML;
				
				if(target_innerHTML){
					if(target_innerHTML.trim() != ""){
						var arr_all_images = target.querySelectorAll("img[src*='blob']");
						
						if(arr_all_images){
							for(var i=0; i<arr_all_images.length; i++){
								if(arr_all_images[i].nextElementSibling){
									var arr_images = arr_all_images[i].parentNode.querySelectorAll("img[src*='blob']");
									
									get_from_page_all_parameters_of_visible_blob_images(arr_images);
								
									return;
								}
							}
						}
					}
				}
				
				target = target.parentNode;
				
				if(!target){ return; }
				
			} while(target);
		}
	}
};

window.addEventListener("click", get_element_containing_blob_image_tags, false);

this.name = '\n Captures the mix of Partial Images generated by "blob" URLs \n\n • Display the Full Image in a new TAB \n\n • Take Screenshot of Full "blob" Image \n ';

this.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACDklEQVQ4jYWRMWgTURjHP0iGgEugFRwEMzgILknve6ggePceJQ5qknfdOmRwcLODxSVDIiZ26JAhTW88sZh7g1IxoNLe5pDB0cHxBpH27oIBkxjICc/hcimGa/zgWz7e//f//u8DWKisWUyjpRuKxX0UPEBL/4KCP1p8F1tK5/6qIriDQpeLvSZKlf8CUPDmTHBCXpc2c68eIFq6Ec54oJj6teUbWLqDQpdKp1T+d857M/DyLbJmMbP3eJ39WMeWy0jP18gdAADscAuFLhVL310K8ChWPIqBx4j0GJGn2o1C7i2/ogh9iEKXRJQ2zxX7THkSCV2Gnz1Gtjba9wxF8EHozp2MqabindXrl1xKJh4j0qPKzjy74Icz8besWcyc6+7O3F1Kvt59dspoY1yljXH1lmG0UGwU1JqaXJrdZ3jgMSJ9SnbVmpPS6qOPtDGSWn000RqjPACArEHyj50oR/2rC6tnERha4frkOQBAHGRwCOnATsqop0eQPYtAsRp+HulFs0WI+bLSnIknUzth/v4Al+eA7+raVY+S8HyqUo6D5F/0Ze9NXk7thBV/CYrN+RkpGn0txwbtdHbw6eLW0713MoJst94/jAU4aiblUnIQQTxG5Hh/RQZ2Uo6PLsjtVjdY/NjY6mtY8BkeuwyH4/ZKMLUTTnCc3OlZNzO0PupqjeFAqw9P1PrP2wAAfwEpM0QpeBBBmQAAAABJRU5ErkJggg==";

Note: The code above must be copied into the "Initialization Code" TAB in Custom Button ( https://forum.palemoon.org/viewtopic.php?f=71&t=32626 ), and Pale Moon must be restarted before using this button.

Note: This code only works if the Full Image is displayed on page using the CSS property "transform / translate3d" (as is the case with "Google Arts & Culture" pages). I haven't tested the code on other sites that use the CSS property "transform / translate3d" (it might work there as well).

HELP:

1. "Ctrl + Alt + Shift" + "Click on Partial Image" = Save the parameters of Partial Image TAGs with "blob" URLs to a variable ( "array" ).

IMPORTANT: This step must be repeated for each new Partial Image obtained by scrolling the previous Partial Image, until every portion of the Full Image is displayed in the browser's window -> See the screenshots below, which show the first two Partial Images parameters (from the first "row") and the last Partial Image parameters (from the last "row") being saved to a variable (there are intermediate Partial Images for which this procedure applies, but I didn't take screenshots of all the necessary steps to capture all the Partial Images that make up the Full Image).

Note: My monitor's resolution is 1360x768, so it's possible that for those with high-resolution monitors (where the full image fits at maximum zoom), a single step (a single "Ctrl + Alt + Shift + Click on Image") might be enough (I can't test this statement).

2. "Ctrl" + "Click on BUTTON" = Display in a new TAB the Full Image created from all the Partial Images ( which were obtained using XMLHttpRequest ) and Take Screenshot of Full Image.

IMPORTANT: This mix of Partial Images is saved to disk as a Single File containing the Full Image.

3. "Shift" + "Click on BUTTON" = Reset the Button Before Using it Again -> Only if the previous use of this Custom Button was not ( successfully ) completed ( by pressing "Ctrl + Click on BUTTON" ).

Screenshots:
01.png
02.png
03.png
04.png
05.png
06.png
07.png
You do not have the required permissions to view the files attached to this post.
Telu (with a single L) was the name of the dog of one of my grandparents - when I was just a little boy.
He was a white dog of large size and very friendly.