{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreiagusleuhu35wh24pu4tkn5qqy2gyqlvsbtw7gahsghi7c7tjgium",
    "uri": "at://did:plc:hqad6xwuzg7oqfmwylfkvqfm/app.bsky.feed.post/3mp4tzkant4d2"
  },
  "path": "/viewtopic.php?t=33521&p=275974#p275974",
  "publishedAt": "2026-06-25T15:59:05.000Z",
  "site": "http://forum.palemoon.org",
  "tags": [
    "https://artsandculture.google.com/asset/napoleon-crossing-the-alps-paul-delaroche/cwF8_mSi8tlbXw",
    "https://forum.palemoon.org/viewtopic.php?f=71&t=32626",
    "@mozilla.org"
  ],
  "textContent": "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.\n\nIn 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.\n\n\nCODE:\n\n\n    /* 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 ordervar 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 ordervar 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 orderarr_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 Againelse 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 variablevar get_element_containing_blob_image_tags = { handleEvent: function(event) {if (event.button == 0 && event.ctrlKey && event.altKey && event.shiftKey){var target = event.targetdo {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==\";\n\n**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.\n\n**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).\n\n**HELP:**\n\n1. \"Ctrl + Alt + Shift\" + \"Click on Partial Image\" = Save the parameters of Partial Image TAGs with \"blob\" URLs to a variable ( \"array\" ).\n\n**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).\n\n**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).\n\n2. \"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.\n\n**IMPORTANT:** This mix of Partial Images is saved to disk as a Single File containing the Full Image.\n\n3. \"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\" ).\n\n**Screenshots:**\n\n\n* * *",
  "title": "Add-ons • Re: is there an addon to rip content protected images?",
  "updatedAt": "2026-06-25T15:59:05.000Z"
}