>> [Musikgengivelse]
>> ZAMYLA CHAN: Det var Miss Scarlett med lysestage.
Krimi?
Nå, vi kommer til at finde ud af.
I brætspillet Clue, kan du givet et fysisk røde billede.
Og at billedet er meget rød og plettet, og dit job er at
afsløre skjulte budskab.
Og som regel er du udstyret med en rød forstørrelsesglas eller et rødt skærmen
viser, at skjult besked.
Nå, vi kommer til at efterligne det.
>> I mordmysterium, får du et bitmap billede der ser meget plettet og rød,
og derefter køre krimi-programmet at afsløre en skjult besked.
>> Så lad os bryde dette i trin.
Først, du ønsker at åbne filen - fingerpeg, at du har fået.
Og så også skabe en Dommen bitmap-fil.
Så du ønsker at opdatere bitmap header info for dommen outfile.
Mere om det senere.
Og så er du kommer til at læse i det fingerpeg, scanlinie, pixel for pixel,
ændre pixel farver nødvendigt, og skrivning
dem i dommen -
pixel for pixel i Dommen scanlinie.
>> Hvordan kan vi begynde at gå om dette?
Nå, heldigvis har vi copy.c i fordelingen kode.
Og det kommer til at bevise ganske nyttigt for os.
Copy.c åbner en fil, læser i det infile overskrift, og opdaterer derefter
outfile overskrift.
Og så læser hver pixel i scanlinie, pixel for pixel, og derefter
skriver, at pixel i outfile.
>> Så dit første skridt måske være at køre følgende
kommando i terminalen -
cp copy.c whodunit.c.
Dette vil skabe en kopi af copy.c opkaldt whodunit.c.
Så vores første skridt til at åbne fil, ja, der er en nøjagtig
replika af at copy.c.
Så jeg vil forlade dig til at se på det.
>> Hvad vi har at gøre med i denne PSET er fil I / O, dybest set at tage filer,
læsning, skrivning, redigere dem.
Hvordan du først åbner en fil?
Nå, er du nødt til at erklære en fil pointer, og derefter ringe dig
funktionen fopen.
Pass i stien, eller navnet på denne fil og derefter den funktion, som du vil
for at åbne filen i.
Passing i en r vil åbne foo.bmp for læsning.
Betragtninger fopen med passerer i en w vil åben bar.bmp, for at skrive filen og
faktisk redigere den.
>> Så nu, at vi har åbnet filen, vores næste skridt er at opdatere header info
for outfile.
Hvad er en header info?
Nå, vi først nødt til at vide hvad en bitmap er.
En bitmap er bare en simpel arrangement af byte.
Og de er erklæret i denne fil her, bmp.h, med en flok
oplysninger om, hvad en bitmap er faktisk lavet af.
Men hvad vi virkelig bekymrer sig om, er bitmap-fil header, lige her, og
bitmap info header, herovre.
Headeren består af et par variabler, der vil vise sig meget nyttig.
Der er biSizeImage, som er samlede størrelse af billedet i byte.
Og dette inkluderer pixels og polstring.
Polstring er meget vigtig, men vi får til senere.
>> BiWidth repræsenterer bredden af billede i pixels minus polstringen.
BiHeight er da også højden af billedet i pixel.
Og så BITMAPFILEHEADER og BITMAPINFOHEADER, som jeg nævnte
tidligere, er de repræsenteret som structs.
Så kan du ikke få adgang til filen header selv, men du vil få lyst til at komme til
disse variabler inde.
>> OK.
Så hvordan vi opdaterer header info?
Nå, vi først nødt til at se, om vi nødt til at ændre alle oplysninger fra
den infile, fingerpeg, til outfile, dommen.
Er der noget ændrer sig i denne sag?
Tja, faktisk ikke, fordi vi vil skal bare ændre farverne.
Vi kommer ikke til at ændre sig filen størrelse, billedets størrelse, bredde,
eller højden.
Så du er okay for nu ved blot at kopiere hver pixel.
>> OK.
Så lad os nu se på, hvordan vi rent faktisk kan læse hver pixel fra filen.
Anden fil I / O-funktion vil komme i spil -
fread.
Det tager i en pointer til struct , der skal indeholde de byte, der
du læser.
Så du læser ind i det.
Og så skal du passere i en størrelse, som er størrelsen af ​​hvert element, som du
vil læse.
Her funktionen sizeof vil komme i handy.
Så er du passerer i antal, som repræsenterer antallet af elementer i
størrelse til at læse.
Og så endelig, inptr, hvilket er filpointeren, at du er
kommer til at læse fra.
Så alle disse elementer er inde inptr og de kommer til data.
>> Lad os se på et lille eksempel.
Hvis jeg ønsker at læse i data to hunde, godt, jeg kan gøre det på to måder.
Jeg kan enten læses på to objekter af størrelse hund fra min inptr, eller jeg kan læse
i et objekt på størrelse med to hunde.
Så du kan se, at afhængigt af den måde at du arrangerer størrelse og antal, du
kan læse i samme antal bytes.
>> Så nu, lad os ændre pixel farve som vi har brug for.
Hvis man ser på bmp.h igen, så du vil se, at i bunden
RGBTRIPLEs er en anden struct, hvor de består af tre bytes.
One, rgbtBlue, rgbtGreen og rgbtRed.
Så hver af disse repræsenterer den mængde blå, mængden af ​​grønt, og
mængden af ​​rødt inde i denne pixel, hvor hvert beløb er repræsenteret ved en
hexadecimalt tal.
>> Så ff0000 vil være en blå farve, fordi det går fra blå,
til grøn, til rød.
Og så F'er bliver hvid.
Lad os tage et kig på smiley.bmp, som du har i din distribution kode.
Hvis du åbner det i bare et billede viewer, så vil du
bare se en rød smiley.
Men at tage et dybere dyk i, vi vil se, at strukturen
af det er bare pixels.
Vi har hvide pixels, og derefter røde pixels.
Den hvide, ffffff og derefter alle de røde pixels jeg har farvet i for dig,
her, og du kan se, at de er 0000FF.
Nul blå, nul grøn og fuld rød.
Og da smiley er otte pixels bred, vi ikke har nogen polstring.
Ok.
>> Så hvis jeg skulle tildele forskellige værdier til en RGBTRIPLE og jeg ønskede at
gøre det grønne, så hvad jeg ville gøre, er Jeg vil erklære en RGBTRIPLE, opkaldt
tredobbelt, og derefter at få adgang til alle byte i denne struct I
ville bruge dot operatør.
Så triple.rgbtBlue, kan jeg tildele det til 0.
Grøn Jeg kan tildele den til fulde - enhver nummer, virkelig, mellem 0 og ff.
Og så rød, jeg vil også sige 0.
Så det giver mig en grøn pixel.
>> Dernæst hvad hvis jeg ønsker at kontrollere værdien af ​​noget?
Jeg kunne have noget, der kontrollerer hvorvidt den tredobbelte s rgbtBlue værdi
FF og derefter udskrive, "Jeg føler mig blå ", som et resultat.
Nu, det betyder ikke nødvendigvis, at pixel er blå, højre?
Fordi pixel grønne og røde værdier kunne også have ikke-0-værdier.
Alt, dette betyder, og alt, dette er at kontrollere for, er
for en fuld blå farve.
Men alle pixels kunne også have delvis farveværdier, som denne
næste eksempel her.
>> Det er lidt sværere at se hvad dette billede er nu.
Det ser lidt mere som clue.bmp, at du vil blive givet.
Nu, fysisk, kan du løse dette, fordi der er en masse af røde, ved
holder op en rød skærm til billedet, så at de andre farver kan vises.
Så hvordan kan vi efterligne dette med c?
Nå, kan vi fjerne alle røde helt fra billedet.
Og så for at gøre, at vi ville sætte hver pixel røde værdi til 0.
Og så billedet ville se lidt lidt ligesom det, hvor vi har ingen rød
eksklusionen.
>> Vi kan se det skjulte budskab en lidt mere klart nu.
Det er en anden smilende ansigt.
Eller måske kunne vi bruge en anden metode.
Måske kunne vi identificere alle de røde pixels -
det vil sige, alle de pixel med 0 blå, 0 grøn og 0 rød -
og ændre dem til hvid.
Og vores image kan se noget som dette.
En lille smule lettere at se.
>> Der er masser af andre måder at afdække det hemmelige budskab så godt,
beskæftiger sig med farven manipulation.
Måske du kan bruge en af ​​de metoder, som jeg nævnte ovenfor.
Og derudover vil du måske at forbedre nogle farver
og bringe dem ud.
>> Så nu, at vi har ændret pixel farve, næste vi bare nødt til at skrive dem
i til scanlinie, pixel for pixel.
Og endnu en gang, vil du ønsker at se tilbage at copy.c, hvis du ikke har kopieret
det allerede, og se på fwrite funktion, der tager data, en pointer
til struct, der indeholder bytes at du læser fra, størrelsen af
de elementer, antallet af elementer, og derefter outptr -
bestemmelsesstedet for disse filer.
>> Når du skriver i pixels, vil du også nødt til at skrive i polstring.
Hvad er polstring?
Nå, hver rgbt pixel tre bytes langt.
Men den scanlinie for et bitmap billede skal være et multiplum af fire bytes.
Og hvis antallet af pixels er ikke multiplum af fire, så er vi nødt til at tilføje
denne polstring.
Polstring er blot repræsenteret ved 0'er.
Så hvordan kan vi skrive eller læse dette?
Tja, det viser sig, at du ikke kan faktisk fread polstring, men du kan
beregne det.
>> I dette tilfælde clue og dommen have samme bredde, så
polstring er den samme.
Og polstring, som du vil se i copy.c, beregnes
med nedenstående formel -
bi.biWidth gange sizeof (RGBTRIPLE) vil give os, hvor mange bytes bmp
har i hver række.
Derfra modulos og subtraktioner med 4 kan beregne, hvor
mange bytes skal tilføjes, således at multiplum af bytes på
hver række er fire.
>> Nu, hvor vi har formlen for hvor meget polstring vi har brug for, nu
vi kan skrive det.
Nu, jeg nævnte før, polstring er kun 0'er.
Så i dette tilfælde, er vi bare at sætte en char, i dette tilfælde et 0, i vores
outptr - vores outfile.
Så det kan bare være fputc 0, komma outptr.
>> Så mens vi har læst i vores fil, har fil I / O holdt styr på vores
position i disse filer med noget kaldte fil positionsindikator.
Tænk på det som en markør.
Dybest set, det fremskridt hver gang at vi fread, men vi har
kontrol over det, også.
>> At flytte filen position indikator, kan du bruge funktionen fseek.
Hvor inptr repræsenterer fil pointer, du søger i, den
mængde er antallet af bytes, som du ønsker at flytte markøren, og derefter fra
angår referencepunktet fra hvor markøren er.
Hvis du passerer i SEEK_CUR, at repræsenterer den aktuelle
position i filen.
Eller du kan bruge nogle andre parametre.
Så kan vi ønsker at bruge fseek at springe over polstring af i filen.
Og igen, hvis du sidder fast, er der et eksempel på, at der i copy.c.
>> Så nu har vi åbnet filen, fingerpeg, og dommen.
Vi har opdateret header info for vores dom, fordi hver
bitmap brug for en header.
Vi har så læs i clue s scanlinie, pixel for pixel, ændre
hver farve som er nødvendigt, og skrive dem ind i
dom, pixel for pixel.
Når du åbner dom, kan du se, hvem synderen, eller hvad den hemmelige
budskab er.
Mit navn er Zamyla, og dette var krimi.