>> [Redare a muzicii]
>> ZAMYLA CHAN: A fost Miss Scarlett cu sfeșnicul.
Roman sau film polițist?
Ei bine, vom afla.
În tabla de joc Clue, s-ar putea se acorde o imagine roșu fizic.
Și că imaginea este foarte roșu și pete, și munca ta este de a
dezvăluie mesajul ascuns.
Și, de obicei, te prevăzut cu un roșu lupă, sau un ecran roșu de
arată că mesajul ascuns.
Ei bine, vom imita asta.
>> În roman sau film polițist, ai dat-o imagine bitmap care arata foarte spotty și roșu,
și apoi executați programul de roman sau film polițist pentru a descoperi un mesaj ascuns.
>> Deci, haideți să rupe acest lucru în etape.
În primul rând, doriți să deschideți fișierul - indiciu că ați fost dat.
Și apoi, de asemenea, crea o fișier verdict bitmap.
Apoi doriți să actualizați bitmap header info pentru outfile verdict.
Mai multe despre asta mai târziu.
Și atunci ai de gând să citesc în indiciu, scanline, pixel cu pixel,
schimbarea culorilor pixelilor ca necesar, și de scris
cei în verdictul -
pixel cu pixel în verdict scanline.
>> Cum putem începe să mergi despre asta?
Ei bine, din fericire, avem copy.c în codul de distribuție.
Și acest lucru se întâmplă pentru a dovedi destul de util pentru noi.
Copy.c deschide un fișier, se arată în antet infile lui, și apoi actualizează
antet outfile lui.
Și apoi se citește fiecare pixel din scanline, pixel cu pixel, și apoi
scrie că pixel în outfile.
>> Deci, primul pas ar putea fie pentru a rula următoarele
comandă în terminal -
cp copy.c whodunit.c.
Acest lucru va crea o copie a copy.c numit whodunit.c.
Deci, primul pas pentru a deschide fișier, ei bine, nu e un exactă
replica de care în copy.c.
Așa că am să vă las să se uite la asta.
>> Ceea ce avem de-a face cu în acest PSET este fișier I / O, ținând practic fișiere,
citirea, scrierea, editarea lor.
Cum vă deschideți mai întâi un fișier?
Ei bine, ai de gând să declare un fișier pointer, și apoi te sun
Funcția fopen.
Trece în calea, sau numele de care dosar, și apoi modul pe care doriți
pentru a deschide acel fișier inch
Trecând într-un r se va deschide foo.bmp pentru lectură.
În timp ce fopen cu trecerea într-un w va bar.bmp deschis, pentru a scrie fișierul și
de fapt editarea.
>> Deci, acum că ne-am deschis dosar, nostru următorul pas este de a actualiza informațiile de antet
pentru outfile.
Ce este un info antet?
Ei bine, în primul rând trebuie să știm ceea ce un bitmap este.
Un bitmap este doar un simplu aranjament de bytes.
Și sunt declarate în acest fișier aici, bmp.h, cu un buchet de
informații a ceea ce un bitmap este, de fapt face din.
Dar ceea ce ne interesează cu adevărat este antet fișier bitmap, chiar aici, și
info antetul bitmap, pe aici.
Antetul este compus dintr-o pereche de variabile care se vor dovedi foarte utile.
Nu este biSizeImage, care este dimensiunea totală a imaginii în bytes.
Și acest lucru include pixeli și padding.
Padding este foarte importantă, dar vom ajunge la asta mai târziu.
>> BiWidth reprezintă lățimea imaginii în pixeli minus padding.
BiHeight este apoi, de asemenea, înălțimea imaginii în pixeli.
Și apoi BITMAPFILEHEADER și BitmapInfoHeader, așa cum am menționat
mai devreme, acestea sunt reprezentate ca structs.
Deci, nu puteți accesa antetul fișierului în sine, dar veți dori pentru a ajunge la
aceste variabile în interiorul.
>> OK.
Deci, cum putem actualiza informațiile antet?
Ei bine, în primul rând trebuie să vedem dacă ne-am trebuie să modificați orice informații de la
infile, indiciu, la outfile, verdictul.
Este orice schimbare in acest caz?
Ei bine, nu, de fapt, pentru că vom să fie doar schimbarea culorilor.
Noi nu o să se schimbe dosar dimensiune, dimensiunea imaginii, lățimea,
sau înălțimea.
Deci, tu ești bine pentru acum prin copierea pur și simplu fiecare pixel.
>> OK.
Deci, acum, să ne uităm la modul în care suntem de fapt poate citi fiecare pixel din dosar.
Un alt fișier de funcții I / O va intra în joc -
fread.
Este nevoie de un pointer la struct care va conține bytes care
sunteți de lectură.
Deci, sunteți de lectură în care.
Și apoi trece într-o dimensiune, care este dimensiunea de fiecare element pe care îl
doresc să citească.
Aici, functia sizeof va veni la îndemână.
Apoi, treci la număr, care reprezintă numărul de elemente ale
dimensiune a citi.
Și apoi în cele din urmă, inptr, care este pointerul de fișier pe care esti
va citi de la.
Deci, toate aceste elemente sunt în interiorul inptr și au de gând să date.
>> Să ne uităm la un mic exemplu.
Dacă vreau să citesc în date de doi câini, ei bine, eu pot face unul din două moduri.
Pot să fie citit în două obiecte de dimensiuni câine de inptr meu, sau eu pot citi
într-un obiect de mărimea doi câini.
Deci, vedeți că, în funcție de modul în care pe care le aranja mărime și număr,
poate citi în același număr de bytes.
>> Deci, acum, să schimbăm pixel culoare ca avem nevoie.
Dacă te uiți la bmp.h din nou, apoi veți vedea că în partea de jos
RGBTRIPLEs sunt un alt struct, în cazul în care acestea sunt alcătuite din trei octeți.
Unul, rgbtBlue, rgbtGreen, și rgbtRed.
Deci, fiecare dintre acestea reprezintă suma de albastru, cantitatea de verde, și
cantitatea de roșu în interiorul acestui pixel, în cazul în care fiecare sumă este reprezentată de un
număr hexazecimal.
>> Deci, FF0000 va fi o culoare albastră, pentru că merge de la albastru,
la verde, la roșu.
Și apoi toate f va fi de culoare albă.
Să aruncăm o privire la smiley.bmp, care aveți în codul de distribuție.
Dacă îl deschideți în doar o imagine vizualizator, atunci veți
a se vedea doar un smiley roșu.
Ci de a lua o scufundare adânc în, vom vedea că structura
din aceasta este doar pixeli.
Avem pixeli albi, și apoi pixeli roșii.
Alb, ffffff, iar apoi tot a pixeli rosii Am colorate pentru tine
aici, și veți vedea că sunt 0000FF.
Zero albastru, verde de zero, și roșu complet.
Si din moment ce smiley este de opt pixeli lățime, nu avem nici o padding.
Bine.
>> Deci, dacă ar fi să atribui valori diferite la un RGBTRIPLE și am vrut să
face verde, atunci ceea ce mi-ar face este Mi-ar declara o RGBTRIPLE, numit
triplu, și apoi pentru a accesa fiecare octet în care struct I
ar folosi operatorul punct.
Deci triple.rgbtBlue, pot atribui că la 0.
Verde pot să-l atribui complet - orice număr, într-adevăr, între 0 și urm.
Și apoi roșu, am, de asemenea, de gând să spun 0.
Deci, care-mi dă un pixel verde.
>> Apoi, ce dacă vreau să verificați valoarea de ceva?
Am putea avea ceva care verifică dacă valoarea tripla lui rgbtBlue este
ff și apoi de imprimare, "Mă simt albastru! ", ca un rezultat.
Acum, că nu înseamnă neapărat care pixel este albastru, nu?
Deoarece valorile verde și roșu pixel ar putea avea, de asemenea, non-0 valori.
Tot ce aceasta înseamnă, și tot ce acest lucru este de verificare este
pentru o culoare albastru complet.
Dar toți pixelii ar putea avea, de asemenea, parțial valori de culoare, cum ar fi aceasta
următorul exemplu aici.
>> Este un pic mai greu pentru a vedea ceea ce această imagine este acum.
Acest lucru pare un pic mai mult ca clue.bmp că veți fi dat.
Acum, fizic, s-ar putea rezolva acest lucru, pentru că există o mulțime de roșu, de
deține un ecran roșu imaginii astfel că alte culori pot apărea.
Deci, cum putem imita acest lucru cu c?
Ei bine, am putea elimina toate roșu din imagine.
Și astfel de a face acest lucru am stabilit fiecare Valoarea roșu pixel la 0.
Și astfel încât imaginea să arate un pic pic ca aceasta, în cazul în care nu avem nici roșu
nici un fel.
>> Putem vedea mesajul ascuns A pic mai clar acum.
Este o altă față zâmbitoare.
Sau poate am putea folosi o altă metodă.
Poate, am putea identifica toți pixelii rosii -
adică, toți pixelii cu 0 albastru, verde 0, 0 și roșu -
și schimbe cei de culoare albă.
Și imaginea noastră s-ar putea uita ceva de genul asta.
Un pic mai ușor pentru a vedea.
>> Există o mulțime de alte moduri de a descoperi mesaj secret, precum și,
care se ocupă cu manipularea culoare.
Poate că ar putea folosi una dintre metodele de pe care am menționat mai sus.
Și, în plus, este posibil să doriți pentru a îmbunătăți unele culori
și să aducă pe cei afară.
>> Deci, acum că ne-am schimbat pixel culoare, următorul trebuie doar să le scrie
în a scanline, pixel cu pixel.
Și încă o dată, veți dori să se uite înapoi la copy.c, dacă nu ați copiat
o deja, si uita-te la fwrite funcție, care preia datele, un indicator
la struct care conține octeții că sunteți de lectură de la, dimensiunea de
elemente, numărul de articole, și apoi outptr -
destinația de acele fișiere.
>> După ce scrie în pixeli, veți au, de asemenea, să scrie în umplutură.
Ce este padding?
Ei bine, fiecare pixel rgbt este de trei bytes lung.
Dar, scanline pentru o imagine bitmap trebuie să fie un multiplu de patru octeți.
Iar dacă numărul de pixeli nu este un multiplu de patru, atunci avem nevoie pentru a adăuga
această umplutură.
Padding este doar reprezentat de 0s.
Deci, cum putem scrie, sau citit asta?
Ei bine, se pare că nu poți umplutură de fapt fread, dar puteți
calcula ea.
>> În acest caz, indiciul și verdictul au aceeași lățime, așa
padding este același.
Și umplutură, așa cum veți vedea în copy.c, se calculează
cu formula de mai jos -
ori bi.biWidth sizeof (RGBTRIPLE) va să ne dea cât de multe bytes BMP
are în fiecare rând.
De acolo, modulos și scăderi cu 4 se poate calcula cât de
mulți octeți Trebuie adăugat, astfel încât multiplul de bytes pe
fiecare rând este de patru.
>> Acum, că avem formula pentru cât de mult avem nevoie de umplutură, acum
putem să-l scrie.
Acum, am menționat mai înainte, padding este doar 0s.
Deci, în acest caz, ne-am doar punerea un char, în acest caz, un 0, în nostru
outptr - outfile nostru.
Astfel că poate fi doar fputc 0, virgulă outptr.
>> Deci, în timp ce am citit în nostru fișier, fișier I / O a ținut evidența noastră
poziție în aceste fișiere cu ceva denumit indicatorul de poziție fișier.
Ganditi-va ca un cursor.
Practic, se avansează de fiecare dată că am fread, dar avem
control asupra acesteia, de asemenea.
>> Pentru a muta indicatorul de poziție fișier, puteți utiliza funcția fseek.
Atunci inptr reprezintă fișierul pointer că sunteți în căutarea în,
Suma este numărul de octeți pe care le doresc pentru a muta cursorul, și apoi de la
se referă la punctul de referință de unde cursorul este.
Dacă treci în SEEK_CUR, care reprezintă curentul
poziția în fișierul.
Sau puteți utiliza unele alți parametri.
Deci, ne-am putea dori să folosească fseek pentru a sări peste peste padding a fișierului în.
Și din nou, dacă te-ai blocat, nu e un exemplu de faptul că, în copy.c.
>> Deci, acum am deschis dosarul, indiciu, și verdictul.
Am actualizat informațiile pentru antet Verdictul nostru, pentru că fiecare
bitmap are nevoie de un antet.
Apoi am citit în indiciu lui scanline, pixel cu pixel, schimbarea
fiecare culoare este necesar, și scris cele în
verdict, pixel cu pixel.
După ce ați deschis verdict, puteți vedea cine vinovat, sau ceea ce secretul
Mesajul este.
Numele meu este Zamyla, și acest lucru a fost roman sau film polițist.