PHP - Notes perso sur Imagick 2 - ImagickDraw... si on dessinait ?

Deuxième épisode de mes notes perso sur la bibliothèque Image magic pour évoquer la classe ImagickDraw qui, comme son nom l'indique, permet de dessiner avec Imagick. ( 1er épisode )

On va se limiter à des usages basiques parce que la lecture du sommaire suffit à imaginer des possibilités certes alléchantes mais totalement hors de propos en ce qui me concerne (courbes de bézier etc)

Spoiler: c'est nettement moins intuitif et simple que pour le traitement d'image... l'écart entre Imagick et GD dans le domaine du tracé n'est plus si évident: ça mériterait de faire un classe pour simplifier tout ça... ( /me se jette sur son bujo pour griffonner spasmodiquement)

Préambule

Cette classe crée un objet servant d'instructions à appliquer ensuite à un objet Imagick.

On partira du principe que vous avez fait des instances des classes comme suit:

$im=new Imagick(); # l'image dans laquelle vous allez appliquer l'objet ImagickDraw
$draw=new ImagikDraw();

Ajouter un texte

Fixer les caractéristiques

  • $draw->setFont(fonte); : sélectionne la fonte à utiliser
  • $draw->setFontSize(taille); : définit la taille en pixels
  • $draw->setFillColor(couleur);: définit la couleur de fond (normalement, couleur est un objet ImagickPixel, voir 1er épisode mais on peut passer une chaîne au format de couleur CSS )
  • $draw->setTextAlignment(alignement); : une des constantes d'alignement imagick::ALIGN_LEFT imagick::ALIGN_CENTER Imagick::ALIGN_RIGHT
  • $draw->setGravity(Imagick::GRAVITY_CENTER); centre le texte dans sa boîte (horizontal et vertical)
  • $draw->setTextDecoration(decoration): une des constantes de décoration imagick::DECORATION_UNDERLINE imagick::DECORATION_OVERLINE imagick::DECORATION_LINETROUGH et bien d'autres (comme du... bruit ?!).
  • $draw->setTextAntialias(true);: ajouter de l'antialias
  • l'espacement :
    • entre les mots : $draw->setTextInterwordSpacing(taille)
    • entre les lignes : $draw->setTextInterlineSpacing(taille)

Tracer le texte

  • $draw->annotation(x,y,texte) : trace un texte dans la police sélectionnée
  • $im->annotateImage( $draw, 0, 0, 0, $fontName ); : ajoute le texte à l'image.

Obtenir des infos utiles

  • obtenir la liste des polices disponibles: $im->queryFonts($pattern = "*") 🆒 on peut filtrer avec une pattern à la façon de glob().
  • obtenir les infos fixées par setXXX : getXXX ... ainsi on a getFont(), getFontSize() etc...
  • obtenir les dimensions de la boîte de texte: $im->queryFontMetrics($draw, text); on récupère un tableau comme ci-dessous
  • 
    Array
    (
        [characterWidth] => 9
        [characterHeight] => 9
        [ascender] => 9 # la taille au-dessus de la baseline
        [descender] => -2 # la taille sous la baseline
        [textWidth] => 71
        [textHeight] => 10
        [maxHorizontalAdvance] => 12
        [boundingBox] => Array
            (
                [x1] => 0
                [y1] => -2
                [x2] => 6.890625
                [y2] => 7
            )
        [originX] => 70
        [originY] => 0
    )
    

    Dessiner des formes

    Fixer les caractéristiques

    • opacité du trait : $draw->setStrokeOpacity(0-1);
    • couleur du trait : $draw->setStrokeColor(couleur);
    • épaisseur du trait : $draw->setStrokewidth(nb);
    • type de trait : $draw->setStrokeDashArray() Le motif semble être plein de possibilités car on peut le définir très spécifiquement et même utiliser une image comme motif (->setStrokePatternURL)
    • couleur de remplissage : $draw->setFillColor(couleur);

    Formes

    • cercle : $draw->circle ($x, $y, $x + $r, $y);
    • ellipse : $draw->ellipse($ox,$oy,$rx,$ry,$start,$end);
    • point : $draw->point ($x, $y);
    • polygone : $draw->polygon ($tableau_de_coordonnées); : array( 'x' => 3, 'y' => 4 ), array( 'x' => 2, 'y' => 6 )
    • ligne brisée : $draw->polyline ($tableau_de_coordonnées); : array( 'x' => 3, 'y' => 4 ), array( 'x' => 2, 'y' => 6 )
    • rectangle : $draw->rectangle ($x, $y, $x2, $y2); )
    • rectangle arrondi: $draw->roundRectangle ($x, $y, $x2, $y2,$rayonx,$rayony);

    Exemple

    Pour écrire un texte dans une image:

    
    $text='pipo et mollo';
    $im=new Imagick();
    $draw=new ImagickDraw();
    //var_dump($im->queryFonts('*'));exit;
    $draw->setFont( 'Courier' );
    $draw->setFontSize( 20 );
    $draw->setFillColor( 'black' );
    $draw->setTextAntialias(true);
    $metrics = $im->queryFontMetrics($draw, $text);
    $draw->annotation(0,$metrics['ascender'],$text);
    $im->newImage( 300, 20, 'lightblue');
    $im->drawImage($draw);
    $im->setImageFormat( 'png' );
    header('Content-type: image/jpeg');
    exit($im);  
    
    ce qui donne cette image
    index2.png
    C'est pas ouf...

    Il serait intéressant de pousser les tests mais là, j'ai pas le temps...

    Peut-être reprendrais-je des trucs existant avec tout ça ( scriptopic, RoR, Stamp mematic etc etc.)

    Et c'est là que Bronco prit  conscience de la quantité de   merdes affligeantes qu'il avait  codées sur un coup de tête  à la va-comme-je-te-pousse   et qu'il avait infligées à tous...

    Api perso: Fetchit, le bon chienchien du oueb...

    Ouate ?

    Après avoir fait goofi puis Getlib j'ai codé vite fait une petite «api» destinée à ramener en local n'importe quelle ressource distante... «quelle différence avec getlib ?» allez-vous me demander sur un ton narquois à propos de la cruauté duquel je tairais scrupuleusement tout commentaire.

    J'ai eu envie de faire ça car j'en avais assez de passer par le combo

    bouton droit sur une ressourcetélécharger envoyer sur mon sitefaire un lien ou une img

    Du coup, il suffit d'ajouter l'adresse de l'api à l'url vers la ressource distante... Donc http://insta.com/image.jpg devient par exemple http://api.warriordudimanche.net/fetchit?url=http://insta.com/image.jpg

    Fetchit va récupérer la ressource en local et vous servir cette version au lieu de la distante. Comme d'hab' si cette ressource a déjà été récupérée elle n'est pas re téléchargée.

    Le deuxième effet kiskool (paye ta réf de vieux) c'est que du coup, comme getlib, ça permet de récupérer toute lib en local et être plus RGPD friendly.

    Examples:

  • utiliser directement une image distante : <img src="http:www.distantserver.com/pic.png"/> ➜ <img src="http://api.url.com?url=http:www.distantserver.com/pic.png"/>
  • lien vers une ressource distante : <a href="http:www.distantserver.com/file.pdf"> Link to distant file</a> ➜ <a href="http://api.url.com?url=http:www.distantserver.com/pic.png"> Link to distant file</a>
  • utiliser une lib hébergée sur un CDN distant : <script src="http:www.distantnastyserver.com/lib.js"></script> ➜ <script src="http://api.url.com?url=http:www.distantnastyserver.com/lib.js"></script>

    Con figue ?

    Afin d'éviter que votre server ne se retrouve floodé par des fichiers vidéos 8K à 60 gigots l'unité, il y a une limite de taille configurée dans la constante SIZE_LIMIT, fixée par défaut à 10 Mo.

    Le code ?! c'est... le code.

    Ceux qui aiment farfouiller verront que cette fois, j'ai fait une classe fetchit_class.php qui se charge de tout. Son fonctionnement est tellement simple que je me fissure même pas le joufflu à vous le détailler, démerdez-vous.

    License

    Comme d'hab', c'est cadeau... Utilisez, partagez, modifiez... juste respectez la Dont be a dick licence

    donne le ouade

    Comme tout ça n'a de sens que si on héberge soi-même, vous pouvez récup' le zip qui va bien ici : https://api.warriordudimanche.net/fetchit/?download

    Le mot final

    Mes chers cons-patriotes, non aux fuites de données, vive le oueb libre et participatif et vive la france et bisou !

  • Installation - guizero gui python

    The aim of guizero is to make the process of creating simple GUIs quick, accessible and understandable for new learners.

    • Works with standard Python Tkinter GUI library (and no need to install other libraries)
    • Abstracts away details new learners find difficult to understand (such as Tkinter StringVar() objects)
    • Accessible widget naming system to help new learners to build up a mental model
    • Flexible enough to be used for projects up to A-Level standard, yet accessible to primary school children
    • Comprehensive and accessible documentation with examples
    • Generates helpful additional error messages

    Liste des widgets: https://lawsie.github.io/guizero/widgetoverview/

    Via https://jcfrog.com/shaarli41/

    GitHub - LeaVerou/md-block: A custom element for rendering stylable (light DOM) Markdown

    Un web component pour faire du markdown facilement par Lea Verou. Hop, de côté.

    • Zero dependencies (except marked, obvs, which is only loaded if a <md-block> or <md-span> element is actually used on the page)
    • Styleable with regular selectors, just like the rest of the page
    • Load external Markdown files or render inline content
    • Customize start heading level
    • Also comes with , for lightweight inline markdown
    • Prism is automatically used for syntax highlighting, if included (but can be included dynamically too)

    Ha zut, comme dit ici https://bookmarks.ecyseo.net/?sAzyVQ ça ne fonctionne que sous chrome.... Merci copain...

    POURQUOI ?! PFFF

    Fil RSS des articles
    Caching time 0.002338 s