Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name BIC EDIT - https://rentry.org/bicedit
- // @description Allows to regenerate an image as square, landscape or portrait with the possibility of fine-tuning it with an additional prompt
- // @version 1.2
- // @match https://copilot.microsoft.com/images/create*
- // @match https://www.bing.com/images/create*
- // @grant GM.setValue
- // @grant GM.getValue
- // @grant unsafeWindow
- // @grant GM.xmlHttpRequest
- // ==/UserScript==
- // Default suggestions for the style textbox, edit these to match your preferences
- // "item1",
- // "item2",
- // Set enableSuggestions to false to disable them
- var enableSuggestions = true;
- var styleSuggestions = [
- "(Open this userscript source code to edit these presets)",
- "monochrome dot-printed manga-style",
- "watercolor",
- "mmd 3d render",
- "fluorescent fiery colors"
- ];
- var refreshIterationsNeeded = 7;
- var isiframe = true;
- var styleTb = null;
- var aspectRatioCb = null;
- var lastRegen = 0;
- var t = null;
- // prevent the script from running on already edited generations since it won't work
- if (shouldExecute()) {
- t = setInterval(update, 1000);
- window.addEventListener('popstate', function (event) {
- if (t == null) {
- console.log("started interval");
- t = setInterval(update, 1000);
- }
- });
- } else {
- checkEditedGenerationImagePage();
- }
- function shouldExecute() {
- var urlParams = new URLSearchParams(window.location.search);
- return urlParams.get("_dbe") === null && window.top === window.self;
- }
- function checkEditedGenerationImagePage() {
- var errorMsg = document.getElementsByClassName("gil_err_mt");
- var errorDesc = document.getElementsByClassName("gil_err_sbt");
- var errorImg = document.getElementsByClassName("gil_err_img rms_img");
- var notFound = errorMsg.length > 0 && errorMsg[0].innerText == "Page not found.";
- if (!notFound) {
- addQueryParamToResult();
- return;
- }
- var useOldBehavior = false;
- var refreshInterval = null;
- errorImg[0].src = "https://r.bing.com/rp/TX9QuO3WzcCJz1uaaSwQAz39Kb0.jpg";
- var updateText = function () {
- errorMsg[0].innerText = "Image generation in progress";
- errorDesc[0].innerText = useOldBehavior ? "This page will refresh automatically every 7 seconds. If the image doesn't appears within 40 seconds, it was most likely filtered and you can close this tab. Refreshing in " + refreshIterationsNeeded + "s..." : "Periodically checking this image generation status...";
- }
- updateText();
- var oldBehavior = function () {
- if (--refreshIterationsNeeded <= 0) {
- location.reload();
- clearInterval(refreshInterval);
- } else {
- updateText();
- }
- };
- var urlParams = new URLSearchParams(window.location.search);
- var skey = urlParams.get("skey");
- var path = window.location.pathname.split('/');
- var genId = path[path.length - 1];
- var onsuccess = function () {
- location.reload();
- clearInterval(refreshInterval);
- };
- var onblocked = function () {
- clearInterval(refreshInterval);
- errorImg[0].src = "https://r.bing.com/rp/in-2zU3AJUdkgFe7ZKv19yPBHVs.png";
- errorMsg[0].innerText = "Image was blocked";
- errorDesc[0].innerText = "";
- document.title = "(Blocked) " + document.title;
- };
- var onfailed = function () {
- useOldBehavior = true;
- };
- if (skey == null) {
- useOldBehavior = true;
- }
- refreshInterval = setInterval(() => {
- if (useOldBehavior) {
- oldBehavior();
- return;
- }
- checkEditStatus(skey, genId, onsuccess, onblocked, onfailed);
- }, 1000);
- }
- function addQueryParamToResult() {
- var results = document.getElementsByClassName("single-img-link");
- for (var i = 0; i < results.length; i++) {
- var element = results[i];
- element.href = element.href + "&_dbe=1"
- }
- }
- function update() {
- var iframe = document.getElementById('OverlayIFrame');
- isiframe = iframe != null;
- var frameElm = iframe ? iframe.contentWindow.document : window.document;
- var detailsElm = frameElm.getElementById("detailMeta");
- var imgd = frameElm.getElementById("msz");
- if (detailsElm != null && imgd != null && imgd.innerText != null) {
- clearInterval(t);
- console.log("stopped interval");
- t = null;
- // BIC returns error if we send an edit request for an image that was already edited so no point in showing the button
- if (imgd.innerText.startsWith("1024 × 1024")) {
- addButton(detailsElm);
- }
- }
- }
- function addButton(detailsElm) {
- var main = detailsElm.getElementsByClassName("actn_container")[0];
- var bingWideContainer = document.createElement("div");
- var generateBtn = document.createElement("div");
- var buttonText = document.createElement("span");
- buttonText.setAttribute("id", "bingwidebuttontext");
- buttonText.setAttribute("style", "color: #953f00;font-weight:bold;font-size:17px;");
- buttonText.innerText = "Generate";
- generateBtn.setAttribute("class", "action nofocus");
- generateBtn.setAttribute("id", "bingwidebutton");
- generateBtn.setAttribute("style", "background-color:#fff0d3;display:inline-block;text-align:center;width:150px;margin-left:20px;");
- generateBtn.onclick = function () {
- // 2 seconds cooldowns to prevent accidental double clicks
- var now = performance.now();
- if (lastRegen + 2000 < now) {
- prepare();
- lastRegen = now;
- } else {
- console.log("blocked - cooldown");
- }
- };
- generateBtn.appendChild(buttonText);
- styleTb = document.createElement("input");
- styleTb.setAttribute("type", "text");
- styleTb.setAttribute("placeholder", "Enter custom style or leave empty to use default 'original'");
- styleTb.setAttribute("id", "bingwidestyle");
- styleTb.setAttribute("maxlength", "100");
- styleTb.setAttribute("spellcheck", "true");
- styleTb.setAttribute("list", "styleSuggestions");
- styleTb.setAttribute("style", "margin-top:15px;width: 440px;text-align: center;background-color: #fff0d3;color: #553030;font-weight: bold;font-size: 15px;");
- bingWideContainer.appendChild(styleTb);
- if (enableSuggestions) {
- var dl = document.createElement("datalist");
- dl.setAttribute("id", "styleSuggestions");
- for (var i = 0; i < styleSuggestions.length; i++) {
- var opt = document.createElement("option");
- opt.setAttribute("value", styleSuggestions[i]);
- dl.appendChild(opt);
- }
- bingWideContainer.appendChild(dl);
- }
- aspectRatioCb = document.createElement("select");
- aspectRatioCb.setAttribute("id", "bingwideaspectratio");
- aspectRatioCb.setAttribute("style", "margin-top:15px;background-color:#fdebca;font-weight:bold;font-size:13px;color:#953f00;");
- var aspectRatios = {
- "0": "Square (1024x1024)",
- "1": "Landscape (1792x1024)",
- "2": "Portrait (1024x1792)"
- }
- for (var x = 0; x < Object.keys(aspectRatios).length; x++) {
- var opt2 = document.createElement("option");
- opt2.setAttribute("value", Object.keys(aspectRatios)[x]);
- opt2.innerText = aspectRatios[x];
- aspectRatioCb.appendChild(opt2);
- }
- var br = document.createElement("br");
- var br2 = document.createElement("br");
- bingWideContainer.appendChild(br);
- bingWideContainer.appendChild(aspectRatioCb);
- bingWideContainer.appendChild(generateBtn);
- main.appendChild(bingWideContainer);
- (async() => {
- var lastUsedStyle = await GM.getValue("style", "original");
- var lastUsedAspectRatio = await GM.getValue("aspectratio", 1);
- if (lastUsedStyle != undefined && lastUsedStyle.toLowerCase() != "original") {
- styleTb.value = lastUsedStyle;
- }
- if (lastUsedAspectRatio >= 0 && lastUsedAspectRatio <= 2) {
- aspectRatioCb.children[lastUsedAspectRatio].setAttribute("selected", "selected");
- }
- var hideMessage = await GM.getValue("hideMessage1", false);
- if (hideMessage) {
- return;
- }
- var messageContainer = document.createElement("div");
- var spanMessage = document.createElement("span");
- spanMessage.setAttribute("style", "white-space:break-spaces;color:#f4d5d5;");
- var spanMessage2 = document.createElement("span");
- spanMessage2.setAttribute("style", "color:#eca26b;");
- var messageOkCb = document.createElement("input");
- messageOkCb.setAttribute("type", "checkbox");
- messageOkCb.setAttribute("name", "hideMessageCb");
- messageOkCb.setAttribute("id", "hideMessageCb");
- var messageLabel = document.createElement("label");
- messageLabel.setAttribute("for", "hideMessageCb");
- messageLabel.setAttribute("style", "color:#fdebca;display:inline;");
- messageLabel.innerText = "Hide this message permanently";
- spanMessage.innerHTML = "<br/>Style can be used to further fine-tune the image. I don't know the full potential of this but think of it as an additional prompt for post-production. There doesn't seems to be a word filter but the visual filter is still active.<br/>Edited generations are opened in a new tab. Make sure to allow popups from this page or the script might get blocked.<br/>";
- spanMessage2.innerHTML = "Each generation attempt still counts towards your account daily limit.";
- spanMessage.appendChild(spanMessage2);
- messageContainer.appendChild(spanMessage);
- messageContainer.appendChild(br2);
- messageContainer.appendChild(messageOkCb);
- messageContainer.appendChild(messageLabel);
- bingWideContainer.appendChild(messageContainer);
- messageOkCb.addEventListener('change', (event) => {
- if (event.currentTarget.checked) {
- GM.setValue("hideMessage1", true);
- bingWideContainer.removeChild(messageContainer);
- }
- });
- })();
- }
- function prepare() {
- var params = new URLSearchParams(window.location.search);
- var querystrings = (isiframe ? unsafeWindow.document.getElementById("OverlayIFrame").contentWindow.window : unsafeWindow).ImageDetailReducers.g_PageConfig.persistedQueryStrings;
- var path = window.location.pathname.split('/');
- var genId = path[path.length - 1];
- var imgId = params.get("id");
- var skey = /skey=(.+?)&/.exec(querystrings)[1];
- var query = (isiframe ? unsafeWindow.document.getElementById("OverlayIFrame").contentWindow.document : unsafeWindow.document).getElementsByClassName("ptitle nolink")[0].innerText;
- if (imgId == null || imgId.length < 5 || skey == null || skey.length < 5) {
- alert("Something went wrong");
- return;
- }
- sendResizeRequest(encodeURIComponent(genId), encodeURIComponent(imgId), encodeURIComponent(skey), encodeURIComponent(query));
- }
- function sendResizeRequest(genid, imgid, skey, query) {
- query = "a cat";
- var style = "original";
- var aspectratio = 1; //0 = square (1024x1024), 1 = landscape (1792x1024), 2 = portrait (1024x1792)
- if (styleTb != null && styleTb.value.length >= 3) {
- style = styleTb.value;
- }
- if (aspectRatioCb != null && aspectRatioCb.selectedIndex != -1) {
- aspectratio = aspectRatioCb.value;
- }
- console.log("Generating this image with an aspect ratio value of '" + aspectratio + "' with the style '" + style + "'.");
- GM.setValue("style", style);
- GM.setValue("aspectratio", aspectratio);
- GM.xmlHttpRequest({
- method: "POST",
- url: "/images/edit/resize?iid=" + imgid + "&skey=" + skey + "&id=" + genid + "&q=" + query + "&partner=Sydney&ar=" + aspectratio + "&s=" + style + "&rt=4",
- onload: function (response) {
- var jsonRes = JSON.parse(response.responseText);
- if (response.status == 200) {
- var urlSplit = jsonRes.webSearchUrl.split('/');
- window.open("/images/create/a-cat/" + urlSplit[urlSplit.length - 1] + "?_dbe=1&skey=" + skey, '_blank');
- } else if (jsonRes.errors[0].message.includes("InvalidOwner")) {
- alert("Request was unsuccessful. You are trying to edit an image that doesn't belongs to the current account you are using.");
- } else if (jsonRes.errors[0].code == ("RateLimitExceeded")) {
- alert("Request was unsuccessful. Your account exceeded rate limit.");
- } else {
- alert("Request was unsuccessful. Unknown error.");
- }
- },
- error: function (event) {
- alert("Couldn't send request.");
- }
- });
- }
- function checkEditStatus(skey, genid, onsuccess, onblocked, onfailed) {
- GM.xmlHttpRequest({
- method: "GET",
- url: "/images/edit/poll?iid=ey%3D%3D&skey=" + skey + "&id=" + genid + "&q=a+cat&partner=Sydney",
- onload: function (response) {
- if (response.status == 404) {
- onfailed();
- return;
- }
- var jsonRes = JSON.parse(response.responseText);
- if (jsonRes._type == "RetrieveImagesResponse" && jsonRes.images != null && jsonRes.images.length > 0) {
- onsuccess();
- } else if (jsonRes._type == "ErrorResponse") {
- onblocked();
- }
- },
- error: function (event) {
- onfailed();
- }
- });
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement