|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="utf-8" /> |
|
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
|
|
|
|
|
<link |
|
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" |
|
rel="stylesheet" |
|
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" |
|
crossorigin="anonymous" |
|
/> |
|
|
|
<script |
|
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" |
|
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" |
|
crossorigin="anonymous" |
|
></script> |
|
|
|
<link rel="stylesheet" href="style.css" type="text/css" /> |
|
|
|
<script |
|
type="module" |
|
src="https://display.truepic.com/truepic_display.es.js" |
|
></script> |
|
</head> |
|
<body> |
|
<div class="container-fluid mt-2" id="head"> |
|
<div class="container"> |
|
<div class="row"> |
|
<div class="col position-relative"> |
|
<div class="row"> |
|
<div class="col"> |
|
<h1> |
|
Title of Space |
|
<div class="badge bg-secondary">experimental</div> |
|
</h1> |
|
<p> |
|
Brief intro explaining the high level concept of this tool. |
|
Eget consequat at proin sed dolor morbi urna. Quam aliquam |
|
imperdiet est lobortis lectus sit vel. |
|
</p> |
|
</div> |
|
</div> |
|
<div class="d-flex flex-row position-absolute bottom-0 tabs"> |
|
<div id="generateTab" class="active"> |
|
<img src="images/generate_icon.svg" /> Generate |
|
</div> |
|
<div id="verifyTab"> |
|
<img src="images/verify_icon.svg" /> Verify |
|
</div> |
|
</div> |
|
</div> |
|
<div class="col right-column"> |
|
<div class="alert alert-secondary" role="alert"> |
|
<h4>Support our work!</h4> |
|
<p>Like this Space in the nav above</p> |
|
<p>Joining the conversation in the Community tab</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="container-fluid" id="body"> |
|
<div class="container"> |
|
<div class="row"> |
|
<div class="col"> |
|
<div class="display-generate"> |
|
<div class="image-container"> |
|
<img src="images/placeholder.png" id="placeholder" /> |
|
<img |
|
src="images/spinner.svg" |
|
id="spinner" |
|
style="display: none" |
|
/> |
|
</div> |
|
</div> |
|
<div class="display-verify"> |
|
<div class="image-container"></div> |
|
</div> |
|
</div> |
|
<div class="col right-column"> |
|
<div class="display-generate"> |
|
<form class="image-gen-form"> |
|
<div class="form-group mb-3"> |
|
<label for="prompt">Image prompt</label> |
|
<textarea id="prompt" class="form-control"></textarea> |
|
</div> |
|
|
|
<div class="form-group mb-3"> |
|
<label>Model</label> |
|
<div class="custom-select"> |
|
<select id="model" class="form-control"> |
|
<option disabled selected value>Select</option> |
|
<option value="runwayml/stable-diffusion-v1-5,1.5"> |
|
runwayml/stable-diffusion-v1-5 |
|
</option> |
|
<option value="CompVis/stable-diffusion-v1-4,1.4"> |
|
CompVis/stable-diffusion-v1-4 |
|
</option> |
|
<option value="stabilityai/stable-diffusion-2-1,2.1"> |
|
stabilityai/stable-diffusion-2-1 |
|
</option> |
|
</select> |
|
</div> |
|
</div> |
|
|
|
<div class="form-check mb-3"> |
|
<input |
|
class="form-check-input" |
|
type="checkbox" |
|
value="" |
|
id="terms" |
|
/> |
|
<label class="form-check-label" for="defaultCheck1"> |
|
By using this demo you agree to the |
|
<a href="#">Terms and Conditions of Truepic and Steg.AI</a> |
|
</label> |
|
</div> |
|
|
|
<button type="submit" class="btn btn-primary">Submit</button> |
|
</form> |
|
|
|
<h3>How it works</h3> |
|
|
|
<p> |
|
Images are generated using a hosted model and AI disclosure is |
|
added to the file. This information, referred to as Content |
|
Credentials, serves as a nutrition label for the content. We |
|
employ the tamper-evident open C2PA standard, which utilizes PKI |
|
and is resistant to forgery. You can download and transfer the |
|
image to supported editing tools like Photoshop, where your edit |
|
history can also be securely added to the file. This historical |
|
information, known as provenance, accompanies your media and can |
|
be extracted and displayed using a tool or website. |
|
</p> |
|
<p>Want to know more? Read our community blog post.</p> |
|
</div> |
|
<div class="display-verify"> |
|
<form class="verify-upload-form" enctype="multipart/form-data"> |
|
<div class="form-group mb-3"> |
|
<label>Upload image</label> |
|
<div class="custom-select"> |
|
<input type="file" class="form-control" /> |
|
</div> |
|
</div> |
|
|
|
<div class="form-check mb-3"> |
|
<input |
|
class="form-check-input" |
|
type="checkbox" |
|
value="" |
|
id="terms" |
|
/> |
|
<label class="form-check-label" for="defaultCheck1"> |
|
By using this demo you agree to the |
|
<a href="#">Terms and Conditions of Truepic and Steg.AI</a> |
|
</label> |
|
</div> |
|
|
|
<button type="submit" class="btn btn-primary">Submit</button> |
|
</form> |
|
|
|
<h3>How it works</h3> |
|
|
|
<p> |
|
Images are generated using a hosted model and AI disclosure is |
|
added to the file. This information, referred to as Content |
|
Credentials, serves as a nutrition label for the content. We |
|
employ the tamper-evident open C2PA standard, which utilizes PKI |
|
and is resistant to forgery. You can download and transfer the |
|
image to supported editing tools like Photoshop, where your edit |
|
history can also be securely added to the file. This historical |
|
information, known as provenance, accompanies your media and can |
|
be extracted and displayed using a tool or website. |
|
</p> |
|
<p>Want to know more? Read our community blog post.</p> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</body> |
|
|
|
<script> |
|
const generateTab = document.querySelector("#generateTab"); |
|
const verifyTab = document.querySelector("#verifyTab"); |
|
const displayVerify = document.querySelectorAll(".display-verify"); |
|
const displayGenerate = document.querySelectorAll(".display-generate"); |
|
const uploadForm = document.querySelector(".verify-upload-form"); |
|
const imageGenForm = document.querySelector(".image-gen-form"); |
|
const placeholder = document.getElementById("placeholder"); |
|
const spinner = document.getElementById("spinner"); |
|
const imagePrompt = document.getElementById("prompt"); |
|
const model = document.getElementById("model"); |
|
|
|
generateTab.addEventListener("click", (event) => { |
|
event.target.classList.add("active"); |
|
verifyTab.classList.remove("active"); |
|
|
|
setGenerateElementsDisplay("block"); |
|
setVerifyElementsDisplay("none"); |
|
}); |
|
|
|
verifyTab.addEventListener("click", (event) => { |
|
event.target.classList.add("active"); |
|
generateTab.classList.remove("active"); |
|
|
|
setGenerateElementsDisplay("none"); |
|
setVerifyElementsDisplay("block"); |
|
}); |
|
|
|
function setGenerateElementsDisplay(displayStatus) { |
|
displayGenerate.forEach((item) => { |
|
item.style.display = displayStatus; |
|
}); |
|
} |
|
|
|
function setVerifyElementsDisplay(displayStatus) { |
|
displayVerify.forEach((item) => { |
|
item.style.display = displayStatus; |
|
}); |
|
} |
|
|
|
uploadForm.addEventListener("submit", (e) => { |
|
e.preventDefault(); |
|
submitForm(); |
|
}); |
|
|
|
function submitForm() { |
|
const formData = new FormData(uploadForm); |
|
|
|
|
|
|
|
|
|
|
|
submitFormData(formData); |
|
} |
|
|
|
function submitFormData(formData) { |
|
fetch("/verify", { |
|
method: "POST", |
|
body: formData, |
|
}) |
|
.then((response) => response.json()) |
|
.then((data) => { |
|
console.log(data); |
|
|
|
const path = "/" + data.response; |
|
|
|
var resultsContainer = document.getElementById("image-container"); |
|
|
|
var truepicDisplay = document.createElement("truepic-display"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
truepicDisplay.setAttribute("id", "result"); |
|
truepicDisplay.setAttribute("active", ""); |
|
var truepic = document.createElement("img"); |
|
truepic.src = path; |
|
|
|
truepicDisplay.appendChild(truepic); |
|
|
|
resultsContainer.appendChild(truepicDisplay); |
|
|
|
}) |
|
.catch((error) => { |
|
console.log(error); |
|
|
|
}); |
|
} |
|
|
|
const generateImage = async (text, model) => { |
|
const inferResponse = await fetch( |
|
`generate?prompt=${text}&model=${model}` |
|
); |
|
const inferJson = await inferResponse.json(); |
|
|
|
return inferJson.response; |
|
}; |
|
|
|
imageGenForm.addEventListener("submit", async (event) => { |
|
event.preventDefault(); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
if (placeholder) placeholder.remove(); |
|
|
|
if (document.getElementById("result")) |
|
document.getElementById("result").remove(); |
|
spinner.style.display = "block"; |
|
|
|
const resp = await generateImage(imagePrompt.value, model.value); |
|
const path = "/" + resp; |
|
|
|
var resultsContainer = document.getElementById("image-container"); |
|
|
|
var truepicDisplay = document.createElement("truepic-display"); |
|
truepicDisplay.addEventListener( |
|
"validate", |
|
setVerificationOutputFromValidation |
|
); |
|
truepicDisplay.addEventListener( |
|
"validate", |
|
setCertificateOutputFromValidation |
|
); |
|
|
|
truepicDisplay.setAttribute("id", "result"); |
|
truepicDisplay.setAttribute("active", ""); |
|
var truepic = document.createElement("img"); |
|
truepic.src = path; |
|
|
|
truepicDisplay.appendChild(truepic); |
|
|
|
spinner.style.display = "none"; |
|
resultsContainer.appendChild(truepicDisplay); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} catch (err) { |
|
console.error(err); |
|
} |
|
}); |
|
</script> |
|
</html> |
|
|