Advertisement
Guest User

codefourni.cpp

a guest
Nov 19th, 2017
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.55 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////////////
  2. /// \file    CodeFourni.cpp
  3. /// \author  Charles Hosson
  4. /// \version Dernière entrée : 2017/11/06
  5. /// \since   Création : 2015/10/11
  6. ///
  7. /// L'implémentation du code fourni aux élèves.
  8. ////////////////////////////////////////////////////////////////////////////////
  9.  
  10.  
  11. #pragma region "Inclusions" //{
  12.  
  13. #include <ciso646>
  14. #include <cstddef>
  15. #include <cstdint>
  16.  
  17. #include <algorithm>
  18.  
  19. #include "CodeFourni.hpp"
  20.  
  21.  
  22. using namespace std;
  23.  
  24. #pragma endregion //}
  25.  
  26.  
  27.  
  28.  
  29. #pragma region "Globaux" //{
  30.  
  31. #pragma region "Fonctions" //{
  32.  
  33. /**
  34.  * Convertit une image en nuance de gris.
  35.  *
  36.  * \param [in,out] image
  37.  *        L'image à convertir.
  38.  */
  39. void convertirNoirEtBlanc ( Image& image )
  40. {
  41.     for ( unsigned i = 0; i < image.hauteur; i++ ) {
  42.         for ( unsigned j = 0; j < image.largeur; j++ ) {
  43.             Pixel couleur = image.pixels[i][j];
  44.             uint8_t nuanceGris = (uint8_t)(((int)couleur.r + couleur.g +
  45.                                             couleur.b) / 3);
  46.             image.pixels[i][j] = {nuanceGris, nuanceGris, nuanceGris};
  47.         }
  48.     }
  49. }
  50.  
  51.  
  52. /**
  53.  * Détermine si les coins du rectangle sont dans le bon ordre, c'est-à-dire
  54.  * \c coin1 est inférieur gauche et \c coin2 est supérieur droit.
  55.  *
  56.  * \param [in] rectangle
  57.  *        Le rectangle à valider.
  58.  *
  59.  * \return Vrai si le rectangle est valide, faux sinon.
  60.  */
  61. bool estRectangleValide ( const Rectangle& rectangle )
  62. {
  63.     return rectangle.coin1.x <= rectangle.coin2.x and
  64.            rectangle.coin1.y <= rectangle.coin2.y;
  65. }
  66.  
  67.  
  68. /**
  69.  * Détermine si une zone donnée fait bien partie de l'image donnée.
  70.  *
  71.  * \param [in] image
  72.  *        L'image contenant la zone.
  73.  * \param [in] rectangle
  74.  *        La zone à valider.
  75.  *
  76.  * \return Vrai si le rectangle est à l'intérieur de l'image. Faux sinon.
  77.  */
  78. bool estZoneValide ( const Image& image, const Rectangle& rectangle )
  79. {
  80.     return estRectangleValide(rectangle) and
  81.            rectangle.coin2.x <= image.largeur and
  82.            rectangle.coin2.y <= image.hauteur;
  83. }
  84.  
  85.  
  86. /**
  87.  * Construit un entête BMP avec les informations spécifiques au TD, mais en
  88.  * laissant vide la taille du fichier.
  89.  *
  90.  * \return Un \c EnteteBmp valide et vide.
  91.  */
  92. EnteteBmp construireBmpVide ( )
  93. {
  94.     EnteteBmp resultat;
  95.    
  96.     resultat.id = BMP_ID;
  97.     resultat.tailleFichier = 0;
  98.     resultat.inutilise[0] = resultat.inutilise[1] = 0;
  99.     resultat.positionTableau = sizeof(EnteteBmp) + sizeof(EnteteDib);
  100.    
  101.     return resultat;
  102. }
  103.  
  104.  
  105. /**
  106.  * Construit un entête DIB avec les informations spécifiques au TD, mais en
  107.  * laissant vide les dimensions de l'image et du tableau de pixels.
  108.  *
  109.  * \return Un \c EnteteDib valide et vide.
  110.  */
  111. EnteteDib construireDibVide ( )
  112. {
  113.     EnteteDib resultat;
  114.    
  115.     resultat.tailleEntete = sizeof(EnteteDib);
  116.     resultat.largeurImage = 0;
  117.     resultat.hauteurImage = 0;
  118.     resultat.nbPlansCouleur = 1;
  119.     resultat.bpp = sizeof(Pixel) * 8;
  120.     resultat.compression = COMPRESSION_BI_RGB;
  121.     resultat.tailleTableau = 0;
  122.     resultat.resolutionImpression[0] = RESOLUTION_IMPRESSION;
  123.     resultat.resolutionImpression[1] = RESOLUTION_IMPRESSION;
  124.     resultat.nbPalettes = 0;
  125.     resultat.nbCouleursImportantes = 0;
  126.    
  127.     return resultat;
  128. }
  129.  
  130.  
  131. /**
  132.  * Calcule le nombre d'octets de \e padding nécessaire pour chaque ligne
  133.  * de pixels dans une image.
  134.  *
  135.  * \param [in] image
  136.  *        L'image à traiter.
  137.  *
  138.  * \return Le nombre d'octet de padding.
  139.  */
  140. unsigned calculerTaillePadding ( const Image& image )
  141. {
  142.     unsigned tailleBruteLigne = image.largeur * sizeof(Pixel);
  143.    
  144.     return (ALIGNEMENT_PIXELS - (tailleBruteLigne % ALIGNEMENT_PIXELS)) %
  145.            ALIGNEMENT_PIXELS;
  146. }
  147.  
  148.  
  149. /**
  150.  * Calcule la taille de la séquence de pixels dans le fichier bitmap, en
  151.  * incluant le padding nécessaire.
  152.  *
  153.  * \param [in] image
  154.  *        L'image à traiter.
  155.  *
  156.  * \return Le nombre d'octet du tableau dans le fichier.
  157.  */
  158. unsigned calculerTailleTableau ( const Image& image )
  159. {
  160.     unsigned padding = calculerTaillePadding(image);
  161.     unsigned tailleLigne = image.largeur * sizeof(Pixel) + padding;
  162.    
  163.     return tailleLigne * image.hauteur;
  164. }
  165.  
  166.  
  167. /**
  168.  * Construit un entête BMP à partir des dimensions d'une image.
  169.  *
  170.  * \param [in] image
  171.  *        L'image à traiter.
  172.  *
  173.  * \return Un \c EnteteBmp complet.
  174.  */
  175. EnteteBmp construireEnteteBmp ( const Image& image )
  176. {
  177.     EnteteBmp resultat = construireBmpVide();
  178.    
  179.     resultat.tailleFichier = sizeof(EnteteBmp) + sizeof(EnteteDib) +
  180.                              calculerTailleTableau(image);
  181.    
  182.     return resultat;
  183. }
  184.  
  185.  
  186. /**
  187.  * Construit un entête DIB à partir des dimensions d'une image.
  188.  *
  189.  * \param [in] image
  190.  *        L'image à traiter.
  191.  *
  192.  * \return Un \c EnteteDib complet.
  193.  */
  194. EnteteDib construireEnteteDib ( const Image& image )
  195. {
  196.     EnteteDib resultat = construireDibVide();
  197.    
  198.     resultat.largeurImage = image.largeur;
  199.     resultat.hauteurImage = image.hauteur;
  200.     resultat.tailleTableau = calculerTailleTableau(image);
  201.    
  202.     return resultat;
  203. }
  204.  
  205.  
  206. /**
  207.  * Trace une ligne horizontale sur une image entre deux points avec une
  208.  * certaine épaisseur (largeur du trait).
  209.  *
  210.  * \param [in,out] image
  211.  *        L'image à modifier.
  212.  * \param [in] couleur
  213.  *        Couleur du trait.
  214.  * \param [in] ligne
  215.  *        Les deux points de la lignes. Ils doivent être alignés en Y.
  216.  * \param [in] epaisseur
  217.  *        Épaisseur du trait, en pixels.
  218.  */
  219. void tracerLigneHorizontale ( Image& image, Pixel couleur, const Point ligne[2], unsigned epaisseur )
  220. {
  221.     unsigned debutX = min(ligne[0].x, ligne[1].x);
  222.     unsigned finX = max(ligne[0].x, ligne[1].x);
  223.    
  224.     unsigned debutY = 0;
  225.     if ( epaisseur / 2 < ligne[0].y )
  226.         debutY = ligne[0].y - epaisseur / 2;
  227.     unsigned finY = debutY + epaisseur;
  228.     if ( finY >= image.hauteur )
  229.         finY = image.hauteur - 1;
  230.    
  231.     for ( unsigned i = debutY; i < finY; i++ ) {
  232.         for ( unsigned j = debutX; j <= finX; j++ )
  233.             image.pixels[i][j] = couleur;
  234.     }
  235. }
  236.  
  237.  
  238. /**
  239.  * Trace une ligne verticale sur une image entre deux points avec une
  240.  * certaine épaisseur (largeur du trait).
  241.  *
  242.  * \param [in,out] image
  243.  *        L'image à modifier.
  244.  * \param [in] couleur
  245.  *        Couleur du trait.
  246.  * \param [in] ligne
  247.  *        Les deux points de la lignes. Ils doivent être alignés en X.
  248.  * \param [in] epaisseur
  249.  *        Épaisseur du trait, en pixels.
  250.  */
  251. void tracerLigneVerticale ( Image& image, Pixel couleur, const Point ligne[2], unsigned epaisseur )
  252. {
  253.     unsigned debutY = min(ligne[0].y, ligne[1].y);
  254.     unsigned finY = max(ligne[0].y, ligne[1].y);
  255.    
  256.     unsigned debutX = 0;
  257.     if ( epaisseur / 2 < ligne[0].x )
  258.         debutX = ligne[0].x - epaisseur / 2;
  259.     unsigned finX = debutX + epaisseur;
  260.     if ( finX >= image.largeur )
  261.         finX = image.largeur - 1;
  262.    
  263.     for ( unsigned i = debutY; i <= finY; i++ ) {
  264.         for ( unsigned j = debutX; j < finX; j++ )
  265.             image.pixels[i][j] = couleur;
  266.     }
  267. }
  268.  
  269.  
  270. /**
  271.  * Dessine un carré plein sur une image.
  272.  *
  273.  * \param [in,out] image
  274.  *        L'image à modifier.
  275.  * \param [in] couleur
  276.  *        Couleur du carré.
  277.  * \param [in] centre
  278.  *        Le centre du carré.
  279.  * \param [in] dimension
  280.  *        Taille du côté du carré, en pixels.
  281.  */
  282. void dessinerCarre ( Image& image, Pixel couleur, const Point& centre, unsigned dimension )
  283. {
  284.     Point ligne[2] = {{0, centre.y}, {0, centre.y}};
  285.    
  286.     if ( dimension / 2 < centre.x )
  287.         ligne[0].x = centre.x - dimension / 2;
  288.     ligne[1].x = ligne[0].x + dimension - 1;
  289.     if ( ligne[1].x >= image.largeur )
  290.         ligne[1].x = image.largeur - 1;
  291.    
  292.     tracerLigneHorizontale(image, couleur, ligne, dimension);
  293. }
  294.  
  295.  
  296. /**
  297.  * Trace un contour de rectangle dans une image.
  298.  *
  299.  * \param [in,out] image
  300.  *        L'image à modifier.
  301.  * \param [in] couleur
  302.  *        Couleur des pixels à tracer.
  303.  * \param [in] rectangle
  304.  *        Rectangle à tracer.
  305.  * \param [in] epaisseur
  306.  *        Épaisseur, en pixels, des côtés du rectangle à tracer.
  307.  */
  308. void tracerContourRectangle ( Image& image, Pixel couleur, const Rectangle& rectangle, unsigned epaisseur )
  309. {
  310.     Point sommets[4];
  311.    
  312.     sommets[0] = rectangle.coin1;
  313.     sommets[1] = {rectangle.coin2.x, rectangle.coin1.y};
  314.     sommets[2] = rectangle.coin2;
  315.     sommets[3] = {rectangle.coin1.x, rectangle.coin2.y};
  316.    
  317.     if ( estZoneValide(image, rectangle) ) {
  318.         for ( int i = 0; i < 4; i++ ) {
  319.             Point ligne[2] = {sommets[i], sommets[(i + 1) % 4]};
  320.            
  321.             if ( i % 2 == 0 )
  322.                 tracerLigneHorizontale(image, couleur, ligne, epaisseur);
  323.             else
  324.                 tracerLigneVerticale(image, couleur, ligne, epaisseur);
  325.            
  326.             dessinerCarre(image, couleur, sommets[i], epaisseur);
  327.         }
  328.     }
  329. }
  330.  
  331. #pragma endregion //}
  332.  
  333. #pragma endregion //}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement