Advertisement
12Me21

new ish converter

Jan 25th, 2018
386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.66 KB | None | 0 0
  1. /*-----*\
  2. | Image |
  3. \*-----*/
  4. var chatDrawCheck=window.setInterval(function () {
  5. if (document.getElementById("chatdraw")) {
  6. window.clearInterval(chatDrawCheck);
  7. converter();
  8. }
  9. }, 100);
  10.  
  11. function converter() {
  12. var drawer = LocalChatDraw.getDrawer();
  13. var canvas = drawer.buffers[0].canvas;
  14. var sidePane = document.querySelector("#sidepane");
  15. var c2d = canvas.getContext("2d");
  16. var cW = canvas.width, cH = canvas.height;
  17. var cR = cW / cH; //width to height ratio
  18. var cM = Math.min(cW, cH); //the smaller dimension
  19.  
  20. ////////////////
  21. //IMAGE UPLOAD//
  22. ////////////////
  23. var z = new Image();
  24. var isImage = false;
  25. //paste box
  26. var pasteImageHere = document.createElement("div");
  27. pasteImageHere.style.width = "3.25rem";
  28. pasteImageHere.contentEditable = true;
  29. pasteImageHere.oninput = function () {
  30. var thing = this.getElementsByTagName("img")[0];
  31. if (thing) {
  32. loadImage(thing.src);
  33. }
  34. while (this.firstChild) {
  35. this.removeChild(this.lastChild); //delete everything
  36. }
  37. };
  38. document.querySelector("#sendpane").appendChild(pasteImageHere);
  39. //file upload button
  40. var fileBrowse = document.createElement("input");
  41. fileBrowse.type = "file";
  42. fileBrowse.onchange = function () {
  43. console.log("User uploaded an image...");
  44. var reader = new FileReader();
  45. reader.readAsDataURL(this.files[0]);
  46. reader.onload = function () {
  47. loadImage(this.result);
  48. };
  49. };
  50. sidePane.appendChild(fileBrowse);
  51. //image loading
  52. function loadImage(source) {
  53. console.log("Found an image. (assume load failed)");
  54. z = new Image();
  55. z.crossOrigin = "Anonymous";
  56. z.onload = function () {
  57. console.log("Image loaded successfully!");
  58. moveBoxParent.style.backgroundImage = "url(\"" + source + "\")";
  59. isImage = true;
  60. updateImage();
  61. };
  62. z.src=source;
  63. }
  64. /////////////////
  65. //image editing//
  66. /////////////////
  67. var elemX=0,elemY=0;
  68. var offsetX,offsetY;
  69. var moving=false;
  70. var scale=1;
  71. const mouseSens=200;
  72.  
  73. //dither slider
  74.  
  75. var ditherSlider = document.createElement("input");
  76. ditherSlider.type = "range";
  77. ditherSlider.min = "0";
  78. ditherSlider.max = "1";
  79. ditherSlider.step = "0.001";
  80. ditherSlider.onchange = function () {
  81. updateImage();
  82. };
  83. sidePane.appendChild(ditherSlider);
  84.  
  85. //auto palette button
  86. var paletteOptimize = document.createElement("button");
  87. paletteOptimize.innerHTML = "palette thing";
  88. paletteOptimize.type = "checkbox";
  89. //stolen from Trinitro21
  90. paletteOptimize.onclick = function () {
  91. var i,x;
  92. var maxHeight = Math.max(z.width / cW,z.height / cH) * cM;
  93. c2d.drawImage(z, elemX / cW * maxHeight * cR, elemY / cH * maxHeight, scale * maxHeight * cR, scale * maxHeight, 0, 0, cW, cH);
  94. var data = c2d.getImageData(0, 0, cW, cH);
  95.  
  96. var high = [0, 0, 0];
  97. var low = [255, 255, 255];
  98. var threshold = [0.8, 0.8, 0.8];
  99. var palette = [];
  100. for (x = 0; x < data.data.length; x += 4) {
  101. for (i = 0; i < 3; i++) {
  102. high[i] = Math.max(high[i], data.data[x + i]);
  103. low [i] = Math.min(low [i], data.data[x + i]);
  104. }
  105. }
  106. var chigh = [high[0] - low[0], high[1] - low[1], high[2] - low[2]];
  107. var prev = [0, 0, 0];
  108. var prevl = 0;
  109. for (x = 0; x < data.data.length; x += 4) {
  110. for (i = 0; i < 3; i++) {
  111. var t = (data.data[x + i] - low[i]) / chigh[i];
  112. threshold[i] += (t * (t * (t - threshold[i]) - threshold[i]) - threshold[i]) / 512;
  113. }
  114. }
  115.  
  116. for (x = 0; x < data.data.length; x += 4) {
  117. var best = Infinity;
  118. var lowindex = -1;
  119. for (i = 0; i < palette.length; i++) {
  120. var cr = palette[i][0] - data.data[x];
  121. var cg = palette[i][1] - data.data[x + 1];
  122. var cb = palette[i][2] - data.data[x + 2];
  123. var a = Math.sqrt(cr * cr + cg * cg + cb * cb);
  124. if (a < best) { //get closest color
  125. best = a;
  126. lowindex = i;
  127. }
  128. }
  129. if (lowindex != -1) {
  130. var errr = Math.abs(data.data[x ] - palette[lowindex][0]);
  131. var errg = Math.abs(data.data[x + 1] - palette[lowindex][1]);
  132. var errb = Math.abs(data.data[x + 2] - palette[lowindex][2]);
  133. if ((errr > chigh[0] * threshold[0] || errg > chigh[1] * threshold[1] || errb > chigh[2] * threshold[2]) && palette.length < 4) {
  134. palette.push([data.data[x], data.data[x + 1], data.data[x + 2]]);
  135. } else {
  136. palette[lowindex][0] += (data.data[x ] - palette[lowindex][0]) / (16384 / best);
  137. palette[lowindex][1] += (data.data[x + 1] - palette[lowindex][1]) / (16384 / best);
  138. palette[lowindex][2] += (data.data[x + 2] - palette[lowindex][2]) / (16384 / best);
  139. }
  140. } else {
  141. palette.push([data.data[x], data.data[x + 1], data.data[x + 2]]);
  142. }
  143. }
  144.  
  145. function setColors(newPalette) {
  146. for (var i = 0; i < newPalette.length; i++) {
  147. var button = document.querySelectorAll("#chatdraw button-area button.colorChange")[i];
  148. var newColorStyle = "rgb(" + newPalette[i].join() + ")";
  149. swapColor(document.querySelector("#chatdraw canvas"), fillStyleToRgb(button.style.color), newPalette);
  150. button.style.color = newColorStyle;
  151. }
  152. updateImage();
  153. }
  154.  
  155. var chatDrawColors = palette;
  156. for (x = 0; x < chatDrawColors.length; x++) {
  157. for (i = 0; i < chatDrawColors[x].length; i++) {
  158. chatDrawColors[x][i] = Math.floor(chatDrawColors[x][i]);
  159. }
  160. }
  161. setColors(chatDrawColors);
  162. };
  163. sidePane.appendChild(paletteOptimize);
  164.  
  165. var updateImageTimeout;
  166. //selection box parent
  167. var moveBoxParent = document.createElement("div");
  168. moveBoxParent.style.width = cW + "px";
  169. moveBoxParent.style.height = cH + "px";
  170. moveBoxParent.style.backgroundSize = "contain";
  171. moveBoxParent.style.backgroundRepeat = "no-repeat";
  172. moveBoxParent.style.backgroundColor = "white";
  173. moveBoxParent.style.border = "1px solid black";
  174. moveBoxParent.onmousemove = function(event) {
  175. if (moving) {
  176. updateMoveBoxPos(event.clientX-offsetX,event.clientY-offsetY);
  177. updatePreview();
  178. }
  179. };
  180. moveBoxParent.onmouseup = moveBoxParent.onmouseleave = function() {
  181. moving = false;
  182. moveBox.style.cursor = "grab";
  183. updateImage();
  184. };
  185. moveBoxParent.onwheel = function(event) {
  186. updateScale(scale + event.deltaY / mouseSens);
  187. updatePreview();
  188. window.clearTimeout(updateImageTimeout);
  189. updateImageTimeout = window.setTimeout(function() {
  190. updateImage();
  191. }, mouseSens);
  192. };
  193. sidepane.appendChild(moveBoxParent);
  194.  
  195. //selection box
  196. var moveBox = document.createElement("div");
  197. moveBox.style.position = "relative";
  198. moveBox.style.border = "1px solid red";
  199. moveBox.style.width = cW - 2 + "px";
  200. moveBox.style.height = cH - 2 + "px";
  201. moveBox.style.cursor = "grab";
  202. moveBox.onmousedown = function(event) {
  203. moving = true;
  204. moveBox.style.cursor = "grabbing";
  205. offsetX = event.clientX - elemX;
  206. offsetY = event.clientY - elemY;
  207. };
  208. moveBoxParent.appendChild(moveBox);
  209.  
  210. //scale slider
  211. var scaleSlider = document.createElement("input");
  212. scaleSlider.type = "range";
  213. scaleSlider.min = 0.0001;
  214. scaleSlider.max = 1;
  215. scaleSlider.step = 0.0001;
  216. scaleSlider.value = 1;
  217. scaleSlider.oninput = function(){
  218. updateScale(this.value);
  219. };
  220. scaleSlider.onchange = function(){
  221. updateImage();
  222. };
  223. sidepane.appendChild(scaleSlider);
  224.  
  225. //blurring checkbox
  226. var blurring = document.createElement("input");
  227. blurring.type = "checkbox";
  228. blurring.checked = false;
  229. blurring.onchange = function() {
  230. c2d.webkitImageSmoothingEnabled = c2d.imageSmoothingEnabled = this.checked;
  231. pc2d.webkitImageSmoothingEnabled = pc2d.imageSmoothingEnabled = this.checked;
  232. updateImage();
  233. };
  234. sidePane.appendChild(blurring);
  235. sidePane.appendChild(document.createTextNode("Smooth Resize"));
  236.  
  237. //movebox functions
  238. function updateScale(newScale) {
  239. var oldScale = scale;
  240. scale = Math.min(Math.max(newScale, 0.001), 1);
  241. var midX = elemX + oldScale * cW / 2;
  242. var midY = elemY + oldScale * cH / 2;
  243. updateMoveBoxPos(midX - scale * cW / 2, midY - scale * cH / 2);
  244. moveBox.style.width = Math.max(scale * cW - 2, 0) + "px";
  245. moveBox.style.height = Math.max(scale * cH - 2, 0) + "px";
  246. scaleSlider.value = scale;
  247. if (oldScale != scale) {
  248. updatePreview();
  249. }
  250. }
  251. function updateMoveBoxPos(x, y) {
  252. elemX = Math.min(Math.max(x, 0), (1 - scale) * cW);
  253. elemY = Math.min(Math.max(y, 0), (1 - scale) * cH);
  254. moveBox.style.left = elemX + "px";
  255. moveBox.style.top = elemY + "px";
  256. }
  257.  
  258. //preview/color picker canvas
  259. var pCanvas = document.createElement("canvas");
  260. pCanvas.width = cW;
  261. pCanvas.height = cH;
  262. pCanvas.style.backgroundColor = "white";
  263. pCanvas.style.border = "1px solid black";
  264. var pc2d = pCanvas.getContext("2d");
  265. pCanvas.onclick = function(event) {
  266. if (isImage) {
  267. var rect = pCanvas.getBoundingClientRect();
  268. var x = Math.round(event.clientX - rect.left - 1);
  269. var y = Math.round(event.clientY - rect.top - 1);
  270. var pixel = pc2d.getImageData(x, y, 1, 1).data;
  271. if (!pixel[3]) {
  272. pixel = [255, 255, 255, 255];
  273. }
  274. var button = document.querySelector("#chatdraw button-area button[data-selected=\"true\"]");
  275.  
  276. button.style.color = rgbToFillStyle(pixel);
  277. console.log("Got color " + pixel.join() + " at " + x + "," + y);
  278. updateImage();
  279. }
  280. };
  281. sidePane.appendChild(pCanvas);
  282.  
  283. ////////////////////
  284. //Image Conversion//
  285. ////////////////////
  286. var colorButtons = document.querySelectorAll("#chatdraw button-area button.colorChange");
  287. var paletteSize = colorButtons.length;
  288. var colorWeight = [3, 6, 1];
  289. document.getElementById("colorPicker").addEventListener("change",function() {
  290. updateImage();
  291. });
  292. document.querySelector("#chatdraw button-area[data-keep=\"true\"] button").addEventListener("click", function() {
  293. isImage = false;
  294. moveBoxParent.style.backgroundImage = "";
  295. pc2d.clearRect(0, 0, cW, cH);
  296. });//x button
  297.  
  298. var sizeButton = document.querySelector("#chatdraw button-area button[data-width]");
  299.  
  300. sizeButton.addEventListener("mousedown", function(event) {
  301. if (event.buttons & 2){
  302. for (var i = 1; i <= 6; i++){
  303. sizeButton.click();
  304. }
  305. }
  306. });
  307.  
  308. sizeButton.addEventListener("contextmenu", function(event) {
  309. event.preventDefault();
  310. });
  311.  
  312. function updateImage() {
  313. if (isImage) {
  314. updatePreview();
  315. putImage(z);
  316. }
  317. }
  318. function updatePreview() {
  319. if (isImage) {
  320. pc2d.clearRect(0, 0, cW, cH);
  321. var maxHeight = Math.max(z.width / cW, z.height / cH) * cM;
  322. pc2d.drawImage(z, elemX / cW * maxHeight * cR, elemY / cH * maxHeight, scale * maxHeight * cR, scale * maxHeight, 0, 0, cW, cH);
  323. }
  324. }
  325. //the actual converter!
  326. function putImage(img) {
  327. var dither = ditherSlider.value;
  328. var i, palette = [];
  329. c2d.rect(0, 0, cW, cH);
  330. c2d.fillStyle = "white";
  331. c2d.fill(); //clear canvas
  332. var maxHeight = Math.max(img.width / cW, img.height / cH) * cM;
  333. c2d.drawImage(img, elemX / cW * maxHeight * cR, elemY / cH * maxHeight, scale * maxHeight * cR, scale * maxHeight, 0, 0, cW, cH);
  334. var data = c2d.getImageData(0, 0, cW, cH);
  335.  
  336. for (i = 0; i < paletteSize; i++) {
  337. palette.push(fillStyleToRgb(colorButtons[i].style.color));
  338. }
  339.  
  340. for (var x = 0, bestIndex, nextErr; x < cW * cH * 4; x += 4) {
  341. //find the best color
  342. var bestDist = Infinity;
  343. for (i = 0; i < paletteSize && bestDist !== 0; i++) {
  344. for (var j = 0, dist = 0, color = palette[i]; j < 3; j++) {
  345. dist += Math.abs(data.data[x + j] - color[j]) * colorWeight[j];
  346. }
  347. if (dist < bestDist){
  348. bestDist = dist;
  349. bestIndex = i;
  350. }
  351. }
  352. //dithering
  353. if (dither){
  354. for (i = 0; i < 3; i++) {
  355. var err = (data.data[x + i] - palette[bestIndex][i]) * dither / 3;
  356. data.data[x + i] = palette[bestIndex][i];
  357. data.data[x + 4 + i] += err; // right
  358. data.data[x + cW * 4 - 4 + i] += err / 2; // bottom left
  359. data.data[x + cW * 4 + i] += err; // bottom
  360. data.data[x + cW * 4 + 4 + i] += err / 2; // bottom right
  361. }
  362. } else {
  363. for (i = 0; i < 3; i++) {
  364. data.data[x + i] = palette[bestIndex][i];
  365. }
  366. }
  367. }
  368. c2d.putImageData(data, 0, 0);
  369. drawer.Redraw();
  370. console.log("Image conversion sucessful.");
  371. }
  372. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement