Le frérot : — Whahahah, géniale ton appli de portfolio, sauf que tu m’as dit que l’avantage d’utiliser Solid, c’était que je pouvais garder le contrôle sur mes photos… Et là, si je les poste avec ton appli sur mon POD, tout le monde peut les récupérer et les copier…
— Attends, ça vient… on va maintenant créer un système pour appliquer un filigrane (watermark en anglais) une marque en plein milieu de ta photo pour que l’on sache que c’est la tienne et qu’on ne puisse pas te la piquer…
On va repartir de ce que l’on a déjà fait et on va tenter d’intégrer avant la publication le filigrane, et pourquoi pas même poster deux versions de chaque photo ? Une dans ton espace privé sans filigrane et un dans ton espace public avec filigrane… Tu es prêt ? Alors reprend ton code et accroche toi…
Si tu es un peu perdu et ne sais pas par où commencer, si tu veux comprendre l’architecture du projet, le mieux c’est de reprendre au premier tutoriel Portfolio Webapp basée sur Solid avec Vuejs
Une fois que tout ça est clair, on peut y aller
Commençons par installer la librairie watermarkjs comme on avait installé les autres avec npm
cd portfolio
npm install --save watermakjs
Bien maintenant que l’on a installé la librairie, on va pouvoir l’importer dans notre fichier /src/components/portfolio/Upload.vue : ajoutez import watermark from ‘watermarkjs’ à la fin des imports déjà présents
/src/components/portfolio/Upload.vue
...
let ldflex = window.solid
import FC from 'solid-file-client'
const fc = new FC( window.solid.auth )
import watermark from 'watermarkjs'
...
On va devoir modifier notre fonction onInput() qui envoyait les photos sur le POD dès qu’elles étaient uploadées dans l’appli. On va maintenant procéder en deux temps : d’abord l’upload, et l’affichage dans un div de prévisualisation, puis l’envoi vraiment vers le POD en cliquant sur un bouton “Envoyer”
D’abord, créons un div de prévisualisation en ajoutant à la ligne </b-form-file> dans le template et profitons-en pour ajouter notre bouton “Envoyer” qui lancera la fonction send() que l’on va créer
<div ref=”preview”></div>
<b-button @click="upload">Envoyer</b-button>
Ensuite, comme évoqué, on va modifier la fonction onInput() qui ressemblait précédemment à
async onInput(files) {
console.log(files)
let storage = await ldflex.data.user.storage
let path = `${storage}`+'public/portfolio/'
console.log(path)
await files.forEach(async function(f) {
console.log(f)
let uri = f.webkitRelativePath.length > 0 ? path+f.webkitRelativePath : path+f.name
console.log(encodeURI(uri))
await fc.createFile(encodeURI(uri), f, f.type)
})
}
par trois fonctions :
On commence par ajouter la procédure trouvée dans la doc de watermarkjs pour insérer du texte, et on récupère le div de previsualisation (preview) auquel on va attacher (append chaque image)
async onInput(files){
console.log(files)
let preview = this.$refs.preview
let storage = await ldflex.data.user.storage
let path = `${storage}`+'public/portfolio/'
await files.forEach(async function(f) {
console.log(f)
watermark([f])
.image(watermark.text.center(path, '30px Josefin Slab', '#fff', 0.8))
.then(img => {
img.name = f.name
img.type = f.type
preview.appendChild(img)});
})
},
Maintenant, lorsque l’on upload des fichiers images, le watermark est appliqué, et chaque image est affichée dans le div preview
On doit ensuite créer la fonction send() qui va permettre d’envoyer ces photos modifier sur le POD de l’utilisateur, en récupérent les images, enfants du div preview (preview.children) . Ceci nous donne une collection HTML (HTML collection que l’on transform en tableau [images] afin de le parcourir. Une petite difficulté supplémentaire, est apparue ici (en même temps, il y a peut-être plus simple pour faire tout ça… Si quelqu’un a des suggestions, laissez un commentaire). On en profite pour ajouter un try{}catch(e){} afin de signaler si l’envoi s’est bien passé ou s’il y a eu une erreur .
async send(){
let preview = this.$refs.preview
let dataURLtoFile = this.dataURLtoFile
var images = [].slice.call(preview.children);
console.log(images)
let storage = await ldflex.data.user.storage
let path = `${storage}`+'public/portfolio/'
console.log(path)
try{
await images.forEach(async function(i) {
let uri = path+i.name
console.log(encodeURI(uri))
var file = dataURLtoFile(i.src,i.name);
await fc.createFile(encodeURI(uri), file, i.type)
})
alert(images.length+" fichiers sauvegardés")
}catch(e){
alert(e)
}
},
Donc la difficulté, c’est que watermarkjs créé la source de nos images en base64 et qu’il faut transformer cette source en fichier image pour qu’elle puisse être envoyée au POD grâce à solid-file-client. La fonction dataUrlToFile() sauvagement piquée sur stackoverflow va nous aider pour cette conversion
dataURLtoFile(dataurl, filename) {var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);while(n--){
u8arr[n] = bstr.charCodeAt(n);
}return new File([u8arr], filename, {type:mime});
},
Si vous avez bien tout suivi, notre fichier
/src/components/portfolio/Upload.vue est maintenant tel que celui-ci
/src/components/portfolio/Upload.vue
<template>
<div class="container">
<b-form-file multiple
accept="image/*"
v-model="files"
:state="Boolean(files)"
placeholder="Choose a file or drop it here..."
drop-placeholder="Drop file here..."
@input="onInput"
></b-form-file>
<div ref="preview"></div>
<b-button @click="send">Envoyer</b-button>
</div>
</template><script>
let ldflex = window.solid
import FC from 'solid-file-client'
const fc = new FC( window.solid.auth )
import watermark from 'watermarkjs'export default {
name: 'Upload',
data() {
return {
files: null
}
},
methods: {
async onInput(files){
console.log(files)
let preview = this.$refs.preview
let storage = await ldflex.data.user.storage
let path = `${storage}`+'public/portfolio/'
await files.forEach(async function(f) {
console.log(f)
watermark([f])
.image(watermark.text.center(path, '30px Josefin Slab', '#fff', 0.8))
.then(img => {
img.name = f.name
img.type = f.type
preview.appendChild(img)});
})
},
async send(){
let preview = this.$refs.preview
let dataURLtoFile = this.dataURLtoFile
var images = [].slice.call(preview.children);
console.log(images)
let storage = await ldflex.data.user.storage
let path = `${storage}`+'public/portfolio/'
console.log(path)
try{
await images.forEach(async function(i) {
let uri = path+i.name
console.log(encodeURI(uri))
var file = dataURLtoFile(i.src,i.name);
await fc.createFile(encodeURI(uri), file, i.type)
})
alert(images.length+" fichiers sauvegardés")
}catch(e){
alert(e)
}
},
dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type:mime});
}
}
}
</script>
Et voili !
La visualisation dans le div “preview”
Et lorsque l’on clique sur le bouton “Envoyer” au dessous des photos, Les versions avec filigrane sont postées sur le POD de l’utilisateur
Il n’y a plus qu’à publier le code sur github pour mettre à jour l’application en ligne avec la commande
npm run git — “filigrane”
Alors frérot ???
Tu créé ton POD et tu postes tes oeuvres dans ton Portfolio, ou tu as encore des questions ?
- all data are stored on solid user’s POD : https://github.com/solid/solid-spec/
- Portfolio webapp hosted on github gh-pages : https://scenaristeur.github.io/portfolio/
- source code : https://github.com/scenaristeur/portfolio
- Tuto EN : https://spoggy-test6.solidcommunity.net/public/blog/portfolio.html
- Tuto FR : La première partie de la création de l’application basée sur Solid à base de vue.js https://dfaveris.medium.com/portfolio-comment-cr%C3%A9er-une-application-web-portfolio-bas%C3%A9e-sur-solid-avec-vue-js-c57b50502d21
- Tuto FR : Publier une webapp sur les gh-pages github https://dfaveris.medium.com/publier-une-application-vuejs-sur-github-ee7662c94667
- Tuto FR : La page de visualisation du portfolio :
https://dfaveris.medium.com/portfolio-2-cr%C3%A9er-la-page-de-pr%C3%A9sentation-du-portfolio-2aad0304d6ad
- Tuto FR : Et le filigrane, dans tout ça ? https://dfaveris.medium.com/et-le-filigrane-sur-mes-photos-b90a6c1e5e40Pour aller plus loin :
poster deux versions de chaque photo : une avec filigrane dans le dossier public, et une sans filigrane dans le dossier private du POD de l’utilisateur
Todo : prochain tuto : mieux gérer la session avec Tracksession et le store vuejs + utiliser le webId pour le filigrane, créer une view de gestion, suppression, renommage des photos, + un album