Public
Edited
Mar 17, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
formData = {
let version = "494ca4d578293b4b93945115601b6a38190519da18467556ca223d219c3af9f9";
return {
version: version,
input: {
model: model,
image: canvasImage.toDataURL()
}
}
}
Insert cell
Insert cell
predict = {
return submit(submitter)
}
Insert cell
submit = function* (formData) {
if(!formData) return null;
// Observable specific thing
yield "loading";

// this tells replicate.com which model to use
let version = "a6ba5798f04f80d3b314de0f0a62277f21ab3503c60c84d4817de83c5edfdae0";
yield fetch(`https://corsproxy.io/?` + encodeURIComponent(`https://api.replicate.com/v1/predictions`), {
// yield fetch(`https://api.replicate.com/v1/predictions`, {
method: 'POST',
headers: {
'Authorization': `Token ${apiKey}`,
// DO NOT set content-type, prevents browser from setting an important boundary property
// 'Content-Type': 'multipart/form-data',
'Accept': "application/json",
},
// body: formData
body: JSON.stringify(formData)
})
.then(response => {
if(response.status !== 200) {
return response.json()
}
return response.json()
})
}
Insert cell
Insert cell
result = {
let data = predict

yield null
// request every half second until its completed
while(data && !data.completed_at && data.created_at && !data.error) {
// console.log("in the loop", data)
if(!predict.urls) {
yield Promises.delay(500, "loading")
continue
}
yield Promises.delay(500, replicatePrediction(predict.urls.get).then(response => {
data = response
return data
}))
}
}
Insert cell
function replicatePrediction(url) {
let predictionOptions = {
method: "get",
headers: {
Authorization: 'Token ' + apiKey,
'Content-Type': 'application/json'
}
}
return d3.json(`https://corsproxy.io/?` + encodeURIComponent(url), predictionOptions)
}
Insert cell
Insert cell
blobify = (canvas) => {
return new Promise((resolve, reject) => {
canvas.toBlob((blob) => {
resolve(blob)
}, 'image/png')
})
}
Insert cell
canvasImage = resizeToCanvas(url)
Insert cell
url = inputImage ? await inputImage.url() : await FileAttachment("wanderer.jpeg").url()
Insert cell
Insert cell
async function resizeToCanvas(url, scale = 1) {
let img = new Image();
img.crossOrigin = '*';
img.src = url;
await new Promise(resolve => img.addEventListener('load', resolve));
let w = img.width
let h = img.height

// resize the image appropriately
let f = factorize(w, h, 512)
let sw = Math.floor(f.width * scale)
let sh = Math.floor(f.height * scale)
let ctx = DOM.canvas(sw, sh).getContext('2d');
ctx.drawImage(img, 0, 0, sw, sh);
ctx.canvas.originalWidth = img.width
ctx.canvas.originalHeight = img.height
return ctx.canvas;
}
Insert cell
function factorize(w, h, target) {
// target should be power of 2 probably, like 512 or 1024
let factor = target / Math.max(w, h)
factor = Math.ceil(Math.min(w, h) * factor / 64) * 64 / Math.min(w, h)
w = Math.floor((w * factor) / 64) * 64
h = Math.floor((h * factor) / 64) * 64
return { width: w , height: h }
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
f = factorize(sampleWidth, sampleHeight, factor)
Insert cell
cf = factorize(canvasImage.originalWidth, canvasImage.originalHeight, factor)
Insert cell
Insert cell
import { loading as spinner } from "@mateh/loading"
Insert cell
import {textcolor} from "@observablehq/text-color-annotations-in-markdown"
Insert cell
// https://talk.observablehq.com/t/when-do-event-listeners-need-to-be-manually-removed/7160
// this lets us cancel a fetch request if our cell's recalculate before the fetch is complete
function toSignal(invalidation) {
const controller = new AbortController;
invalidation.then(() => controller.abort());
return controller.signal;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more