Novembre 2024 | Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
---|
| | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | Calendrier |
|
|
| Extraire une partie d'image bmp | |
| | Auteur | Message |
---|
JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Extraire une partie d'image bmp Mar 21 Déc 2010 - 16:24 | |
| Ceci est un clin d'oeil à Klaus, pour son jeu de belote. Le problème est qu'il faut joindre au programme au moins 52 images bmp correspondant aux 52 cartes. Il existe un fichier bmp: cards.bmp contenant l'ensemble des images des 52 cartes, que j'ai mis ici: http://www.2shared.com/photo/dLfMRTOA/cards.htmlEt voici un petit programme qui reconstitue les 52 images à partir de ce fichier unique, en extrayant les cartes une à une (numérotées arbitrairement de 0 à 51). Mais ça peut servir également à créer un fichier bmp à partir d'une zone d'un autre bmp, connaissant les coordonnées et les dimensions de la zone à extraire. - Code:
-
' Extraction individuelle en bmp des 52 cartes du fichier des cartes Cards.bmp DIM fc$, fr$, j%, x%, y%, nbc%, nbr%, lc%, nc%, hc%, c%, r%, ll%, lr% DIM buf$, lgt%, et$, sz%, w%, h%, tf%, ti%, bpp% DIM rep$, a$, b$ LABEL Lircards, Carte ' ========================== A AJUSTER ================================ fc$ = "C:\Graph\Bmp\Cards.bmp": ' 923x384, = (71x13) x (96x4) 4 fois 13 cartes rep$ = "Z:": ' répertoire résultat pour les 52 cartes en bmp ' ===================================================================== GOSUB Lircards nbc% = 13: nbr% = 4: ' colonnes et rangées dans le fichier image cards.bmp lc% = INT(ll%/bpp%*nbc%): hc% = h%/4: ' 1 carte, en pixels: 71x96 lr% = bpp%*lc% + lc%-4*INT(lc%/4): ' longueur ligne résultante
' Nouveau header a$ = CHR$(256*FRAC(20502/256)) + CHR$(INT(20502/256)) + CHR$(0)+CHR$(0): ' taille fichier et$ = LEFT$(et$, 2) + a$ + MID$(et$, 7, LEN(et$)) a$ = CHR$(256*FRAC(20448/256)) + CHR$(INT(20448/256)) + CHR$(0)+CHR$(0): ' taille image et$ = LEFT$(et$, 34) + a$ + MID$(et$, 39, LEN(et$)) a$ = CHR$(lc%)+CHR$(0)+CHR$(0)+CHR$(0)+CHR$(hc%)+CHR$(0)+CHR$(0)+CHR$(0): ' dimensions et$ = LEFT$(et$, 18) + a$ + MID$(et$, 27, LEN(et$))
nc% = 49: ' n° de la carte à extraire (0 à 51) PRINT "Génération des 52 cartes..." FOR nc% = 0 TO 51 GOSUB Carte NEXT nc% END
Lircards: ' lecture du fichier image cards.bmp dans et$ et buf$ ' les cartes sont sur 4 rangées de 13 cartes, trèfle, carreau, coeur, pique, ' de As, 2, 3 etc. jusqu'à Dame, Roi. Chaque image carte fait 71x96 pixels. FILEBIN_OPEN_READ 1,fc$: sz% = FILEBIN_SIZE(1): FILEBIN_CLOSE 1 FILE_OPEN_READ 1, fc$: FILE_READBUF 1, buf$, sz%: FILE_CLOSE 1 lgt% = ASC(MID$(buf$,11,1)): ' taille du header (=54) et$ = LEFT$(buf$, lgt%): ' en-tête bmp (54 octets) buf$ = MID$(buf$, lgt%+1, LEN(buf$)): ' image w% = ASC(MID$(et$,19,1))+256*ASC(MID$(et$,20,1))+256*256*ASC(MID$(et$,21,1)) h% = ASC(MID$(et$,23,1))+256*ASC(MID$(et$,24,1))+256*256*ASC(MID$(et$,25,1)) tf% = ASC(MID$(et$,3,1))+256*ASC(MID$(et$,4,1))+256*256*ASC(MID$(et$,5,1)) ti% = ASC(MID$(et$,35,1))+256*ASC(MID$(et$,36,1))+256*256*ASC(MID$(et$,37,1)) bpp% = ASC(MID$(et$,29,1))/8: ' octets par pixel ll% = ti%/h%: ' longueur d'une ligne graphique, en octets RETURN
Carte: ' création fichier carte de la carte numéro nc%: fr$ fr$ = rep$ + "Carte"+RIGHT$("0"+STR$(nc%), 2)+".bmp": ' de la forme Cartexx.bmp r% = INT(nc%/nbc%): ' rangée c% = nbc%*(nc%/nbc%-r%): ' colonne x% = c% * lc% * bpp%: ' octet début dans la ligne (3 octets par pixel) y% = r% * ll% * hc%: ' début de la ligne x% = y% + x% b$ = et$ FILE_OPEN_WRITE 1, fr$ FOR j% = 0 TO hc%-1 b$ = b$ + MID$(buf$, 1+x%, lc%*bpp%) + STRING$(lc%-4*INT(lc%/4), CHR$(0)) x% = x% + ll% NEXT j% FILE_WRITEBUF 1, b$, LEN(b$) FILE_CLOSE 1 RETURN | |
| | | Nardo26
Nombre de messages : 2294 Age : 56 Localisation : Valence Date d'inscription : 02/07/2010
| Sujet: Re: Extraire une partie d'image bmp Mar 21 Déc 2010 - 21:01 | |
| Merci JL35, c'est exactement le bout de code à mettre de coté en cas de besoin... | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Extraire une partie d'image bmp Mar 21 Déc 2010 - 21:31 | |
| Merci Nardo, on ne te voyait plus... Je vais faire quelque chose de plus général et moins spécialisé dans les cartes: extraction dans un bmp de la partie de longueur l et de hauteur h, en x et y, ce sera un sous-ensemble de ci-dessus, mais d'usage plus général.
On peut aussi faire des choses amusantes dans un bmp, quand on connaît la structure, par exemple dessiner des figures, superposer une autre image, etc., tout ça par programme, en bricolant dans le fichier. | |
| | | Nardo26
Nombre de messages : 2294 Age : 56 Localisation : Valence Date d'inscription : 02/07/2010
| Sujet: Re: Extraire une partie d'image bmp Mar 21 Déc 2010 - 22:57 | |
| Oui, comme je l'ai dis à Klaus, j'ai réécris entièrement mon site wouaib... et ca m'a pris pas mal de temps.... mais je suis de retour ! Tu as l'air calé dans le traitement des images... Quand est-ce que tu nous fait un prog de traitement d'images HDR ? | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Extraire une partie d'image bmp Mar 21 Déc 2010 - 23:28 | |
| Bon, il va falloir que j'aille revisiter ton site alors. Oh non hélas, je ne suis pas calé dans l'imagerie, je me suis juste penché sur le format bmp qui est de loin le plus simple (avec quelques petits pièges), rien à voir avec la complexité des formats compressés (jpg par exemple). Comme j'avais dit, un petit programme plus généraliste, pour extraire une partie d'image d'une image bmp (coordonnées x%, y%, dimensions l% et h%). En fait, pour manipuler le fichier d'origine, je le lis entièrement dans une variable buf$, une fois pour toutes, et là c'est beaucoup plus facile pour accéder aux différents éléments, avec MID$. (je détourne un peu les fonctions FILE_READBUF et FILE_WRITEBUF qui sont prévues pour des fichiers texte et que j'utilise avec du binaire, mais ça marche très bien, et c'est bien pratique. Mais il ne faudrait sans doute pas faire ça avec un très gros fichier). - Code:
-
' Extraction individuelle en bmp d'une partie d'image d'un fichier bmp DIM fc$, fr$, i%, j%, x%, y%, xi%, yi%, l%, h%, ll%, lr%, fill% DIM lgh%, wi%, hi%, tf%, ti%, bpp%, tin%, tfn%, v%(5000) LABEL Extraire ' ========================== A AJUSTER ================================ fc$ = "C:\Graph\Bmp\cards.bmp": ' Image bmp d'origine fr$ = "Z:\Test.bmp": ' Image bmp extraite ' =====================================================================
x% = 852: y% = 192: l% = 71: h% = 96: ' image à extraire GOSUB Extraire EXECUTE_WAIT "C:\Progra~1\Irfanv~1\i_view32.exe " + fr$: ' pour voir TERMINATE END
Extraire: ' caractéristiques du fichier image bmp fc$ FILEBIN_OPEN_READ 1,fc$ FILEBIN_BLOCK_READ 1, 54, v%(0): ' header lgh% = v%(10): ' taille du header (= 54 octets) wi% = v%(18)+256*v%(19)+256*256*v%(20): ' largeur image hi% = v%(22)+256*v%(23)+256*256*v%(24): ' hauteur image tf% = v%(2)+256*v%(3)+256*256*v%(4): ' taille totale fichier ti% = v%(34)+256*v%(35)+256*256*v%(36): ' taille image bpp% = v%(28)/8: ' octets par pixel ll% = ti%/hi%: ' longueur d'une ligne graphique, en octets lr% = bpp%*l% + l%-4*INT(l%/4): ' longueur ligne graphique résultante, en octets tin% = lr% * h%: ' taille de l'image du fichier créé tfn% = tin% + lgh%: ' taille totale du fichier créé (=image + header) v%(2) = BIN_AND(tfn%,255): v%(3) = BIN_AND(INT(tfn%/256),255) v%(4) = BIN_AND(INT(tfn%/65536),255): ' taille du nouveau fichier -> header v%(34) = BIN_AND(tin%,255): v%(35) = BIN_AND(INT(tin%/256),255) v%(36) = BIN_AND(INT(tin%/65536),255): ' taille de la nouvelle image -> header v%(18) = BIN_AND(l%,255): v%(19) = BIN_AND(INT(l%/256),255): ' largeur v%(22) = BIN_AND(h%,255): v%(23) = BIN_AND(INT(h%/256),255): ' hauteur y% = y% + h% xi% = x% * bpp% yi% = (hi%-y%)*ll%+lgh%: xi% = xi% +yi% fill% = 0: IF FRAC(l%/4) > 0 THEN fill% = l%-4*INT(l%/4): ' octets de complément FILEBIN_OPEN_WRITE 2, fr$ FILEBIN_BLOCK_WRITE 2, lgh%, v%(0): ' écriture du nouveau header FOR j% = 0 TO h%-1 FILEBIN_POSITION 1, xi% FILEBIN_BLOCK_READ 1, l%*bpp%, v%(0): FILEBIN_BLOCK_WRITE 2, l%*bpp%, v%(0) IF fill% > 0 THEN FOR i% = 1 TO fill%: FILEBIN_WRITE 2, 0: NEXT i% xi% = xi% + ll% NEXT j% FILEBIN_CLOSE 2 FILEBIN_CLOSE 1 RETURN MON PROGRAMME NE VAUT RIEN, ET JE ME SUIS FAIT AVOIR ENCORE UNE FOIS !En effet, le FILE_READBUF ne convient pas en l'occurence, puisque dès qu'il rencontre le caractère 26 ('1A') il ne lit plus rien et remplit tout le reste avec ce même caractère. La longueur du string buf$ est bien égale à la taille du fichier, mais rempli de caractères 1A ! Ca marche pour le fichier des cartes cards.bmp, qui ne contient pas ce caractère, mais pour d'autres fichiers ça ne marche plus. Alors il va falloir utiliser le FILEBIN_BLOCK_READ qui ne me plaît pas, parce que: - il est limité je crois à 2000 octets <------ Faux !- il lit dans un tableau dont l'usage est beaucoup moins pratique que le string. Et s'il faut lire octet par octet avec FILEBIN_READ, c'est rédhibitoire. Donc, je cale un peu... DERNIERES NOUVELLESPS Finalement j'ai changé de méthode et je lis et écris directement en binaire dans les fichiers, et c'est plus rapide que ce que je craignais. Donc, a priori le code mis à jour ci-dessus fonctionne. | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Extraire une partie d'image bmp Jeu 23 Déc 2010 - 17:22 | |
| Finalement j'ai fait quelque chose d'un peu mieux structuré et plus universel: - Code:
-
' Extraction individuelle en bmp d'une partie d'image d'un fichier bmp DIM fc$, fr$, i%, j%, x%, y%, xi%, yi%, l%, h%, ll%, lr%, fill% DIM lgh%, wi%, hi%, tf%, ti%, bpp%, tin%, tfn% DIM lfi%, lfo%, val%, pbo%, nbo%, vbo%(5000) LABEL Extraire, LirBmp, EcrBmp, Getvbo, Putvbo ' ========================== A AJUSTER ================================ fc$ = "C:\Graph\Bmp\joc1.bmp": ' Image bmp d'origine fr$ = "Z:\Test.bmp": ' Image bmp extraite ' =====================================================================
x% = 130: y% = 160: l% = 145: h% = 40: ' Exemple: image à extraire de fc$ dans fr$ GOSUB Extraire ' EXECUTE_WAIT "C:\Progra~1\Irfanv~1\i_view32.exe " + fr$: ' IrfanView, pour voir le résultat ' TERMINATE END ' +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Sous-programmes +-+-+-+-+-+-+-+-+-+-+-+-+-+-+- Extraire: ' Extraction dans fr$ d'une image extraite de fc$ en x%, y%, l%, h% lfi% = 1: FILEBIN_OPEN_READ lfi%, fc$ lfo% = 2: FILEBIN_OPEN_WRITE lfo%, fr$ pbo% = -1: nbo% = 54: GOSUB LirBmp: ' lecture du header bmp pbo% = 10: nbo% = 1: GOSUB Getvbo: lgh% = val%: ' taille du header (54 octets) pbo% = 18: nbo% = 4: GOSUB Getvbo: wi% = val%: ' largeur image pbo% = 22: nbo% = 4: GOSUB Getvbo: hi% = val%: ' hauteur image pbo% = 2: nbo% = 4: GOSUB Getvbo: tf% = val%: ' taille totale fichier pbo% = 34: nbo% = 4: GOSUB Getvbo: ti% = val%: ' taille image pbo% = 28: nbo% = 1: GOSUB Getvbo: bpp% = val%/8: ' octets par pixel ll% = ti%/hi%: ' longueur d'une ligne graphique origine, en octets lr% = bpp%*l% + l%-4*INT(l%/4): ' longueur ligne graphique résultante, en octets tin% = lr% * h%: ' taille de l'image du fichier créé tfn% = tin% + lgh%: ' taille totale du fichier créé (=image + header) pbo% = 2: nbo% = 4: val% = tfn%: GOSUB Putvbo: ' taille du nouveau fichier -> header pbo% = 34: nbo% = 4: val% = tin%: GOSUB Putvbo: ' taille de la nouvelle image -> header pbo% = 18: nbo% = 4: val% = l%: GOSUB Putvbo: ' largeur image pbo% = 22: nbo% = 4: val% = h%: GOSUB Putvbo: ' hauteur image pbo% = -1: nbo% = lgh%: GOSUB EcrBmp: ' écriture du nouveau header y% = y% + h% xi% = x% * bpp% yi% = (hi%-y%)*ll%+lgh%: xi% = xi% + yi% fill% = lr% - l%*bpp%: ' octets de complément éventuels (doit être multiple de 4) FOR j% = 0 TO h%-1 pbo% = xi%: nbo% = l%*bpp%: GOSUB LirBmp pbo% = -1: GOSUB EcrBmp IF fill% > 0 THEN FOR i% = 1 TO fill%: FILEBIN_WRITE lfo%, 0: NEXT i% xi% = xi% + ll% NEXT j% FILEBIN_CLOSE lfo%: FILEBIN_CLOSE lfi% RETURN
LirBmp: ' Lecture dans le fichier ouvert lfi% à la position pbo% de nbo% octets dans vbo%(0) IF pbo% > -1 THEN FILEBIN_POSITION lfi%, pbo%: ' position courante si pbo% = -1 FILEBIN_BLOCK_READ lfi%, nbo%, vbo%(0) RETURN
EcrBmp: ' Écriture dans le fichier ouvert lfo% à la position pbo% de nbo% octets depuis vbo%(0) IF pbo% > -1 THEN FILEBIN_POSITION lfo%, pbo%: ' position courante si pbo% = -1 FILEBIN_BLOCK_WRITE lfo%, nbo%, vbo%(0) RETURN
Getvbo: ' Lire la valeur val% à partir de vbo%(pbo%), sur nbo% octets, poids faibles d'abord val% = 0 FOR i% = 0 TO nbo%-1 val% = val% + POWER(256,i%)*vbo%(pbo%+i%) NEXT i% RETURN
Putvbo: ' Ranger la valeur val% à partir de vbo%(pbo%), sur nbo% octets, poids faibles d'abord FOR i% = 0 TO nbo%-1 vbo%(pbo%+i%) = BIN_AND(INT(val%/POWER(256,i%)), 255) NEXT i% RETURN | |
| | | Contenu sponsorisé
| Sujet: Re: Extraire une partie d'image bmp | |
| |
| | | | Extraire une partie d'image bmp | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |