🏠 Home 

Download Origin Image from Doubao without Watermark 从豆包下载无水印图片

Download Origin Image from www.doubao.com without Watermark. 从豆包(www.doubao.com)下载无水印图片


Install this script?
  1. // ==UserScript==
  2. // @name 从豆包下载无水印图片 Download Origin Image from Doubao without Watermark
  3. // @name:en Download Origin Image from Doubao without Watermark 从豆包下载无水印图片
  4. // @namespace https://github.com/catscarlet/Download-Origin-Image-from-Doubao-without-Watermark
  5. // @description 从豆包(www.doubao.com)下载无水印图片 Download Origin Image from www.doubao.com without Watermark.
  6. // @description:en Download Origin Image from www.doubao.com without Watermark. 从豆包(www.doubao.com)下载无水印图片
  7. // @version 0.5.0
  8. // @author catscarlet
  9. // @license GNU Affero General Public License v3.0
  10. // @match https://www.doubao.com/chat/*
  11. // @run-at document-end
  12. // @grant none
  13. // ==/UserScript==
  14. const removeDefaultDownloadButton = 1; //Hide Original Download Button by default. If you want the default Download Button appear as usual, set this value to 0.
  15. (function() {
  16. 'use strict';
  17. let throttleTimer;
  18. let debounceTimer;
  19. const observer = new MutationObserver((mutationsList) => {
  20. const now = Date.now();
  21. if (!throttleTimer || now - throttleTimer > 300) {
  22. throttleTimer = now;
  23. clearTimeout(debounceTimer);
  24. debounceTimer = setTimeout(() => {
  25. for (const mutation of mutationsList) {
  26. if (mutation.type === 'childList') {
  27. if (removeDefaultDownloadButton) {
  28. const EditImageDownloadButtons = document.querySelectorAll('div[data-testid="edit_image_download_button"]');
  29. EditImageDownloadButtons.forEach((EditImageDownloadButton) => {
  30. if (EditImageDownloadButton && EditImageDownloadButton.style.display != 'none') {
  31. EditImageDownloadButton.style.display = 'none';
  32. }
  33. });
  34. }
  35. const images = document.querySelectorAll('img.preview-img-fe4pbK.img-bg-l0S60q');
  36. if (images.length == 0) {
  37. return false;
  38. }
  39. images.forEach((image) => {
  40. if (!image.parentNode.querySelector('.imagelink-nowatermark')) {
  41. const link = document.createElement('a');
  42. link.textContent = '点击下载无水印图片';
  43. link.style.whiteSpace = 'break-spaces';
  44. link.classList.add('imagelink-nowatermark');
  45. link.style.position = 'absolute';
  46. link.style.backgroundColor = '#007BFF';
  47. link.style.color = 'white';
  48. link.style.padding = '10px 20px';
  49. link.style.border = 'none';
  50. link.style.borderRadius = '5px';
  51. link.style.zIndex = 1;
  52. link.style.textDecoration = 'none';
  53. link.style.opacity = '0.8';
  54. const x = 0;
  55. const y = 0;
  56. link.style.left = x + 'px';
  57. link.style.top = y + 'px';
  58. link.addEventListener('mouseover', function() {
  59. this.style.backgroundColor = '#0056b3';
  60. this.style.cursor = 'pointer';
  61. });
  62. link.addEventListener('mouseout', function() {
  63. this.style.backgroundColor = '#007BFF';
  64. this.style.cursor = '';
  65. });
  66. link.addEventListener('click', async () => {
  67. getCrossOriginImage(link);
  68. });
  69. image.parentNode.appendChild(link);
  70. } else {
  71. //console.log('added, skip.');
  72. }
  73. });
  74. }
  75. }
  76. }, 300);
  77. }
  78. });
  79. const config = {
  80. childList: true,
  81. attributes: false,
  82. subtree: true,
  83. };
  84. observer.observe(document.documentElement, config);
  85. })();
  86. async function getCrossOriginImage(link) {
  87. const currentTitle = document.title.replace('- 豆包', '').trim();
  88. const chatID = document.location.pathname.replace('/chat/', '').trim();
  89. const timeStr = getYmdHMS();
  90. const imageUrl = link.parentNode.querySelector('img').src;
  91. const imageName = currentTitle + '-' + chatID + '-' + timeStr + '.png';
  92. try {
  93. const response = await fetch(imageUrl, {mode: 'cors'});
  94. const blob = await response.blob();
  95. const url = URL.createObjectURL(blob);
  96. const a = document.createElement('a');
  97. a.href = url;
  98. a.download = imageName;
  99. a.style.display = 'none';
  100. document.body.appendChild(a);
  101. setTimeout(() => {
  102. a.click();
  103. }, 10);
  104. setTimeout(() => {
  105. URL.revokeObjectURL(url);
  106. document.body.removeChild(a);
  107. }, 1000);
  108. } catch (error) {
  109. console.error('图片加载失败,请确保图片服务器开启了 CORS 支持。');
  110. alert('图片加载失败,请确保图片服务器开启了 CORS 支持。');
  111. }
  112. }
  113. function getYmdHMS() {
  114. const date = new Date();
  115. const Y = date.getFullYear();
  116. const m = String(date.getMonth() + 1).padStart(2, '0');
  117. const d = String(date.getDate()).padStart(2, '0');
  118. const H = String(date.getHours()).padStart(2, '0');
  119. const M = String(date.getMinutes()).padStart(2, '0');
  120. const S = String(date.getSeconds()).padStart(2, '0');
  121. const r###lt = `${Y}${m}${d}${H}${M}${S}`;
  122. return r###lt;
  123. }