>> [Musikk spilles]
>> ZAMYLA CHAN: Det var Miss Scarlett med lysestaken.
Whodunit?
Vel, vi kommer til å finne ut.
I brettspillet Clue, kanskje du gis en fysisk rødt bilde.
Og det bildet er veldig rød og flekkete, og din jobb er å
avdekke skjulte budskap.
Og vanligvis du er utstyrt med en rød forstørrelsesglass, eller en rød skjerm til
avslører at skjulte budskap.
Vel, vi skal etterligne det.
>> I whodunit, får du et bitmap-bilde som ser veldig ustabil og rød,
og deretter kjøre whodunit program å avdekke et skjult budskap.
>> Så la oss bryte dette i trinn.
Først ønsker du å åpne filen - ledetråd som du har fått.
Og da også skape en Dommen bitmap fil.
Så du ønsker å oppdatere bitmap header info for dommen outfile.
Mer om det senere.
Og så kommer dere til å lese inn i anelse, scanline, piksel for piksel,
endre pixel farger som nødvendig, og skriving
de inn i dommen -
piksel for piksel i det Dommen scanline.
>> Hvor skal vi begynne å gå om dette?
Vel, heldigvis, har vi copy.c i fordelingskode.
Og dette kommer til å bevise ganske nyttig for oss.
Copy.c åpner en fil, leser i den infile header, og deretter oppdaterer
outfile header.
Og så leser hver piksel i scanline, piksel for piksel, og deretter
skriver at pixel inn i outfile.
>> Så, det første trinnet kan være å kjøre følgende
kommando i terminalen -
cp copy.c whodunit.c.
Dette vil skape en kopi av copy.c heter whodunit.c.
Så vår første skritt til å åpne fil, vel, det er en eksakt
kopi av det i copy.c.
Så jeg vil forlate deg til å se på det.
>> Hva vi har å gjøre med i denne PSett er fil I / O, i utgangspunktet å ta filer,
lese, skrive, redigere dem.
Hvordan kan du først åpne en fil?
Vel, du kommer til å erklære en fil pekeren, og deretter du ringe
funksjonen fopen.
Pass på banen, eller navnet på det fil, og deretter den modusen du vil
å åpne denne filen i.
Passerer i en r vil åpne foo.bmp for lesing.
Mens fopen med bestått i en w vil åpen bar.bmp, for skriving til fil og
faktisk å redigere den.
>> Så nå som vi har åpnet filen, vår Neste steg er å oppdatere header info
for outfile.
Hva er en header info?
Vel, først må vi vite hva en bitmap er.
Et bitmap er bare en enkel arrangement av bytes.
Og de er deklarert i denne filen her, bmp.h, med en haug med
informasjon om hva et bitmap er faktisk laget av.
Men det vi virkelig bryr seg om er bitmap fil header, akkurat her, og
bitmap info header, over her.
Toppteksten er sammensatt av et par variabler som vil være svært nyttig.
Det er biSizeImage, som er totale størrelsen på bildet i byte.
Og dette inkluderer piksler og polstring.
Padding er svært viktig, men vi får til det senere.
>> BiWidth representerer bredden på bildet i piksler minus padding.
BiHeight er da også høyden av bildet i piksler.
Og så BITMAPFILEHEADER og BITMAPINFOHEADER, som jeg nevnte
tidligere, er de som er representert som structs.
Så, kan du ikke få tilgang til filen header seg selv, men du vil ønske å komme til
disse variablene inne.
>> OK.
Så hvordan oppdaterer vi overskriften info?
Vel, først må vi se om vi trenger å endre noe av informasjonen fra
den infile, ledetråd, til outfile, dommen.
Er det noe som endrer seg i denne saken?
Vel, ikke egentlig, fordi vi skal skal bare endre fargene.
Vi kommer ikke til å være i endring filen størrelse, vil bildestørrelsen, bredden,
eller høyden.
Så du er all right for nå ved bare å kopiere hver piksel.
>> OK.
Så nå la oss se på hvordan vi faktisk kan lese hver piksel fra filen.
En annen fil I / O-funksjon kommer inn i bildet -
fread.
Det tar i en peker til struct som skal inneholde de bytes som
du leser.
Så du leser inn i det.
Og så du passerer i en størrelse, som er størrelsen på hvert element som du
ønsker å lese.
Her funksjonen sizeof vil komme godt med.
Da passerer du i antall, noe som representerer antallet elementer i
størrelse til å lese.
Og til slutt, inptr, som er filen peker som du er
skal lese fra.
Så alle disse elementene er inne inptr og de kommer til data.
>> La oss se på et lite eksempel.
Hvis jeg ønsker å lese inn data to hunder, vel, jeg kan gjøre det på to måter.
Jeg kan enten lese i to objekter av størrelse hund fra min inptr, eller jeg kan lese
i et objekt på størrelse med to hunder.
Så du ser at avhengig av hvordan at du ordne størrelse og antall, du
kan lese i samme antall byte.
>> Så nå, la oss endre pixel farge som vi trenger.
Hvis du ser på bmp.h igjen, da vil du se at på bunnen
RGBTRIPLEs er en annen struct, hvor de består av tre bytes.
One, rgbtBlue, rgbtGreen, og rgbtRed.
Så hver av disse representerer mengden blått, mengden av grønt, og den
mengde røde inni denne pixel, hvor hvert beløp er representert med en
heksadesimale tall.
>> Så FF0000 vil være en blå farge, fordi det går fra blått,
til grønt, til rødt.
Og så alle f-er vil være hvit.
La oss ta en titt på smiley.bmp, som du har i din distribusjon kode.
Hvis du åpner den i bare et bilde seer, så vil du
bare se en rød smiley.
Men å ta et dypere dykk i, vi vil se at konstruksjonen
av er det bare piksler.
Vi har hvite piksler, og deretter røde piksler.
Den hvite, ffffff, og deretter hele røde piksler Jeg har farget i for deg
her, og du ser at de er 0000FF.
Zero blå, null grønn, og full red.
Og siden smiley er åtte piksler bred, vi har ikke noe padding.
OK.
>> Så hvis jeg skulle tildele forskjellige verdier til en RGBTRIPLE og jeg ønsket å
gjøre det grønne, så hva jeg ville gjøre er Jeg ville erklære en RGBTRIPLE, oppkalt
trippel, og deretter å få tilgang til alle byte innenfor denne struct jeg
ville bruke dot operatør.
Så triple.rgbtBlue, kan jeg tilordne dette til 0.
Grønn Jeg kan tildele det til fulle - noe nummer, egentlig, mellom 0 og ff.
Og så rødt, jeg også kommer til å si 0.
Så da det gir meg en grønn piksel.
>> Neste, hva om jeg ønsker å sjekke verdien av noe?
Jeg kunne ha noe som sjekker om trippel er rgbtBlue verdi er
ff og deretter skrive ut, "Jeg føler blue ", som et resultat.
Nå, det betyr ikke nødvendigvis at at pixel er blå, ikke sant?
Fordi piksel grønne og røde verdier kan også ha ikke-0-verdier.
Alt som dette innebærer, og alt som dette er å sjekke for er
for en full blå farge.
Men alle pikslene kan også ha delvis fargeverdier, som dette
neste eksempel her.
>> Det er litt vanskeligere å se hva dette bildet er nå.
Dette ser litt mer ut som clue.bmp at du vil bli gitt.
Nå, fysisk, kan du løse dette, fordi det er mye rødt, etter
holder opp en rød skjerm til bildet slik at de andre fargene kan dukke opp.
Så hvordan skal vi etterligne dette med c?
Vel, vi kan fjerne alle røde fra bildet i sin helhet.
Og så for å gjøre det vi ville sett hver pixel røde verdien til 0.
Og slik at bildet vil se litt litt som dette, hvor vi har ingen rød
hodet.
>> Vi kan se det skjulte budskapet en litt mer tydelig nå.
Det er en annen smiley face.
Eller kanskje vi kunne bruke en annen metode.
Kanskje kan vi identifisere alle de røde piksler -
det vil si alle pikslene med 0 blå, 0 grønn, og 0 rød -
og endre dem til hvit.
Og vårt bilde kan se ut noe sånt som dette.
Litt lettere å se.
>> Det er mange andre måter å avdekke den hemmelige budskap i tillegg,
arbeider med farge manipulasjon.
Kanskje du kan bruke en av metodene som nevnt ovenfor.
Og i tillegg, vil du kanskje å forbedre noen farger
og ta dem ut.
>> Så nå som vi har endret pixel farge, neste vi trenger bare å skrive dem
inn til scanline, piksel for piksel.
Og enda en gang, vil du ønsker å se tilbake å copy.c, hvis du ikke har kopiert
det allerede, og se på fwrite funksjon, som tar data, en peker
til struct som inneholder bytes at du leser fra, størrelsen på
elementene, antall elementer, og deretter outptr -
målet for disse filene.
>> Etter at du har skrive i piksler, vil du må også skrive i padding.
Hva er padding?
Vel, hver rgbt pixel er tre byte.
Men, den scanline for et punktgrafikkbilde må være et multiplum av fire bytes.
Og hvis antall piksler er ikke et multiplum av fire, så vi må legge
dette padding.
Padding er bare representert ved 0s.
Så, hvordan kan vi skrive, eller lese dette?
Vel, det viser seg at du ikke kan faktisk fread padding, men du kan
beregne det.
>> I dette tilfellet, anelse og dommen har den samme bredde, slik at
polstring er den samme.
Og padding, som du vil se i copy.c, beregnes
med følgende formel -
bi.biWidth ganger sizeof (RGBTRIPLE) vil gi oss hvor mange byte den bmp
har i hver rad.
Derfra modulo og subtraksjonene med 4 kan beregne hvor
mange byte må legges slik at multiplum av byte på
hver rad er fire.
>> Nå som vi har formelen for hvor mye padding vi trenger, nå
vi kan skrive det.
Nå nevnte jeg før, padding er bare 0s.
Så i dette tilfellet, vi bare å sette en røye, i dette tilfellet en 0, inn i vår
outptr - vår outfile.
Så det kan bare være fputc 0, komma outptr.
>> Så, mens vi har lest i vår fil, har fil I / O holdt orden på vår
posisjon i disse filene med noe heter filen posisjonsindikator.
Tenk på det som en markør.
I utgangspunktet, fremskritt det hver gang at vi fread, men vi har
kontroll over det, også.
>> Å flytte filen posisjonsindikator, du kan bruke funksjonen fseek.
Der inptr representerer filen peker som du søker i,
beløpet er antall byte som du ønsker å flytte markøren, og deretter fra
vedrører referansepunktet fra der markøren er.
Hvis du passerer i SEEK_CUR, at representerer den nåværende
posisjon i filen.
Eller du kan bruke noen andre parametere.
Så, kanskje vi ønsker å bruke fseek å hoppe over polstring av i filen.
Og igjen, hvis du sitter fast, er det et eksempel på dette i copy.c.
>> Så nå har vi åpnet filen, ledetråd, og dommen.
Vi har oppdatert overskriften info for Vår dom, fordi hver
bitmap trenger en header.
Vi har deretter leses inn i ledetråd er scanline, piksel for piksel, skiftende
hver farge som er nødvendig, og skriver de inn i
dommen, piksel for piksel.
Når du åpner dommen, kan du se hvem som den skyldige, eller hva hemmeligheten
meldingen er.
Mitt navn er Zamyla, og dette var whodunit.