1 00:00:00,000 --> 00:00:09,500 >> [Muziek] 2 00:00:09,500 --> 00:00:12,350 >> ZAMYLA CHAN: Het was Miss Scarlett met de kandelaar. 3 00:00:12,350 --> 00:00:13,560 Wie? 4 00:00:13,560 --> 00:00:15,030 Nou, we gaan uitzoeken. 5 00:00:15,030 --> 00:00:20,870 In het bordspel Cluedo, zou je worden voorzien van een fysieke kopie rood. 6 00:00:20,870 --> 00:00:24,120 En dat beeld is zeer rood en vlekkerige, en uw taak is om 7 00:00:24,120 --> 00:00:25,490 onthullen de verborgen boodschap. 8 00:00:25,490 --> 00:00:29,740 En meestal je bent voorzien van een rode vergrootglas, of een rood scherm 9 00:00:29,740 --> 00:00:31,410 blijkt dat verborgen boodschap. 10 00:00:31,410 --> 00:00:33,340 Nou, we gaan na te bootsen dat. 11 00:00:33,340 --> 00:00:37,960 >> In whodunit, bent u een bitmapafbeelding gegeven dat ziet er zeer onregelmatig en rood, 12 00:00:37,960 --> 00:00:43,430 en voer het whodunit programma een verborgen boodschap onthullen. 13 00:00:43,430 --> 00:00:45,650 >> Dus laten we breken deze in stappen. 14 00:00:45,650 --> 00:00:50,390 Eerst moet je het bestand wilt openen - de aanwijzing die je hebt gekregen. 15 00:00:50,390 --> 00:00:53,880 En dan ook nog een maken verdict bitmap-bestand. 16 00:00:53,880 --> 00:00:58,240 Dan wil je de bitmap te werken header info op de uitspraak outfile. 17 00:00:58,240 --> 00:00:59,920 Daarover later meer. 18 00:00:59,920 --> 00:01:04,319 En dan moet je gaan om te lezen in de aanwijzing, scanline, pixel voor pixel, 19 00:01:04,319 --> 00:01:07,320 veranderen van de pixel kleuren nodig, en schrijven 20 00:01:07,320 --> 00:01:08,960 die in het vonnis - 21 00:01:08,960 --> 00:01:12,000 pixel voor pixel in de verdict scanline. 22 00:01:12,000 --> 00:01:13,780 >> Hoe beginnen we te gaan over dit? 23 00:01:13,780 --> 00:01:16,940 Nou, gelukkig hebben we copy.c in de verdeelsleutel. 24 00:01:16,940 --> 00:01:21,240 En dit gaat te bewijzen heel nuttig voor ons. 25 00:01:21,240 --> 00:01:29,700 Copy.c een bestand opent, leest in die infile kopbal, en werkt vervolgens de 26 00:01:29,700 --> 00:01:31,070 header outfile's. 27 00:01:31,070 --> 00:01:37,010 En dan leest elke pixel in het scanline, pixel voor pixel, en vervolgens 28 00:01:37,010 --> 00:01:42,390 schrijft dat pixel in de outfile. 29 00:01:42,390 --> 00:01:45,020 >> Dus, uw eerste stap zou kunnen zijn de volgende run 30 00:01:45,020 --> 00:01:46,420 commando in de terminal - 31 00:01:46,420 --> 00:01:50,270 cp copy.c whodunit.c. 32 00:01:50,270 --> 00:01:55,320 Hierdoor wordt een kopie van te maken copy.c genaamd whodunit.c. 33 00:01:55,320 --> 00:01:58,320 Dus onze eerste stap om te openen de file, goed, er is een exacte 34 00:01:58,320 --> 00:02:00,070 replica van die in copy.c. 35 00:02:00,070 --> 00:02:03,360 Dus ik zal je laten kijken. 36 00:02:03,360 --> 00:02:07,860 >> Wat we met deze PSET wordt file I / O, in principe nemen bestanden, 37 00:02:07,860 --> 00:02:10,229 lezen, schrijven, ze te bewerken. 38 00:02:10,229 --> 00:02:12,650 Hoe doe je eerst een bestand openen? 39 00:02:12,650 --> 00:02:16,800 Nou, je gaat naar een bestand te verklaren wijzer, en dan bel je de 40 00:02:16,800 --> 00:02:18,670 functie fopen. 41 00:02:18,670 --> 00:02:23,150 Passeren in het pad, of de naam van die bestand, en vervolgens de gewenste modus 42 00:02:23,150 --> 00:02:24,700 om dat bestand te openen in 43 00:02:24,700 --> 00:02:28,620 Passeren in een r zal openen foo.bmp voor het lezen. 44 00:02:28,620 --> 00:02:35,670 Overwegende fopen met het passeren in een w zal geopend bar.bmp, voor het schrijven van het bestand en 45 00:02:35,670 --> 00:02:37,020 eigenlijk bewerken. 46 00:02:37,020 --> 00:02:41,970 >> Dus nu dat we het bestand hebt geopend, onze volgende stap is om de header info updaten 47 00:02:41,970 --> 00:02:43,230 voor de outfile. 48 00:02:43,230 --> 00:02:44,610 Wat is een header info? 49 00:02:44,610 --> 00:02:48,160 Nou, ten eerste moeten we weten wat een bitmap is. 50 00:02:48,160 --> 00:02:51,000 Een bitmap is gewoon een simpel arrangement bytes. 51 00:02:51,000 --> 00:02:55,480 En ze zijn verklaard in dit bestand hier, bmp.h, met een stel 52 00:02:55,480 --> 00:02:58,610 informatie van wat een bitmap is eigenlijk gemaakt uit. 53 00:02:58,610 --> 00:03:05,730 Maar wat we echt zorgen over de bitmap-bestand header, hier, en 54 00:03:05,730 --> 00:03:08,460 de bitmap info header, hier. 55 00:03:08,460 --> 00:03:13,170 De header bestaat uit een paar variabelen die zeer nuttig zal blijken. 56 00:03:13,170 --> 00:03:18,400 Er is biSizeImage, de totale grootte van de afbeelding in bytes. 57 00:03:18,400 --> 00:03:20,890 En dit omvat pixels en opvulling. 58 00:03:20,890 --> 00:03:24,210 Padding is erg belangrijk, maar zullen we later op terug. 59 00:03:24,210 --> 00:03:30,000 >> BiWidth voor de breedte van de afbeelding in pixels minus de opvulling. 60 00:03:30,000 --> 00:03:34,220 BiHeight is dan ook de hoogte van de afbeelding in pixels. 61 00:03:34,220 --> 00:03:38,240 En dan de BITMAPFILEHEADER en de BITMAPINFOHEADER, zoals ik al zei 62 00:03:38,240 --> 00:03:40,900 eerder, die worden vertegenwoordigd als structs. 63 00:03:40,900 --> 00:03:45,410 Ja, kunt u geen toegang tot het bestand header zelf, maar je wilt krijgen 64 00:03:45,410 --> 00:03:47,370 deze variabelen binnen. 65 00:03:47,370 --> 00:03:48,170 >> OK. 66 00:03:48,170 --> 00:03:50,600 Dus hoe kunnen we een update van de header info? 67 00:03:50,600 --> 00:03:54,020 Nou, eerst moeten we zien of we moet alle informatie van veranderen 68 00:03:54,020 --> 00:03:58,480 de infile, de aanwijzing, het outfile, het vonnis. 69 00:03:58,480 --> 00:04:00,250 Is iets te veranderen in dit geval? 70 00:04:00,250 --> 00:04:04,320 Nou, eigenlijk niet, want we gaan gewoon veranderen de kleuren. 71 00:04:04,320 --> 00:04:07,550 We gaan niet naar het bestand te veranderen grootte, het beeldformaat, de breedte, 72 00:04:07,550 --> 00:04:08,310 of de hoogte. 73 00:04:08,310 --> 00:04:14,010 Dus je bent goed voor nu door gewoon kopiëren van elke pixel. 74 00:04:14,010 --> 00:04:14,840 >> OK. 75 00:04:14,840 --> 00:04:20,720 Dus laten we nu eens kijken hoe we eigenlijk kan elke pixel te lezen uit het bestand. 76 00:04:20,720 --> 00:04:23,640 Andere file I / O-functie zal komen in het spel - 77 00:04:23,640 --> 00:04:24,700 fread. 78 00:04:24,700 --> 00:04:28,440 Het neemt in een pointer naar de struct dat zal de bytes bevatten dat 79 00:04:28,440 --> 00:04:30,110 je leest. 80 00:04:30,110 --> 00:04:31,890 Dus je leest in die. 81 00:04:31,890 --> 00:04:36,090 En dan heb je pas in een grootte, die is de omvang van elk element dat u 82 00:04:36,090 --> 00:04:37,360 wilt lezen. 83 00:04:37,360 --> 00:04:40,640 Hier, de functie sizeof zal van pas komen. 84 00:04:40,640 --> 00:04:45,570 Dan pas je in getal, die geeft het aantal elementen van 85 00:04:45,570 --> 00:04:47,480 maat te lezen. 86 00:04:47,480 --> 00:04:51,180 En tenslotte, inptr, hetgeen de file pointer die je 87 00:04:51,180 --> 00:04:52,530 gaan lezen uit. 88 00:04:52,530 --> 00:04:58,650 Dus al die elementen zijn binnen inptr en ze gaan van gegevens. 89 00:04:58,650 --> 00:05:01,660 >> Laten we eens kijken naar een klein voorbeeld. 90 00:05:01,660 --> 00:05:07,590 Als ik wil lezen in data twee honden, Nou, ik kan het doen op twee manieren. 91 00:05:07,590 --> 00:05:15,250 Ik kan zowel lezen in twee objecten van grootte hond van mijn inptr, of ik kan lezen 92 00:05:15,250 --> 00:05:19,280 in een object de grootte van twee honden. 93 00:05:19,280 --> 00:05:23,580 Zo zie je maar dat afhankelijk van de manier waarop dat u regelen grootte en aantal, u 94 00:05:23,580 --> 00:05:25,840 lezen in hetzelfde aantal bytes. 95 00:05:25,840 --> 00:05:28,720 96 00:05:28,720 --> 00:05:33,020 >> Dus nu, laten we veranderen de pixel kleur als we nodig hebben. 97 00:05:33,020 --> 00:05:37,320 Als je kijkt naar bmp.h weer, dan zie je dat aan de onderkant 98 00:05:37,320 --> 00:05:42,920 RGBTRIPLEs zijn een andere structuur, waar zij bestaan ​​uit drie bytes. 99 00:05:42,920 --> 00:05:49,220 Een, rgbtBlue, rgbtGreen en rgbtRed. 100 00:05:49,220 --> 00:05:52,480 Dus elk van deze is het bedrag blauw, de hoeveelheid groen en de 101 00:05:52,480 --> 00:05:57,250 hoeveelheid rood in deze pixel, waar elk bedrag wordt vertegenwoordigd door een 102 00:05:57,250 --> 00:05:58,670 hexadecimaal getal. 103 00:05:58,670 --> 00:06:04,370 >> Dus ff0000 zal een blauwe kleur, want het gaat van blauw, 104 00:06:04,370 --> 00:06:05,850 groen, rood. 105 00:06:05,850 --> 00:06:09,300 En dan zijn alle f's wit zijn. 106 00:06:09,300 --> 00:06:13,440 Laten we eens een kijkje nemen op smiley.bmp, die je hebt in je distributie code. 107 00:06:13,440 --> 00:06:15,690 Als je het in slechts een afbeelding te openen kijker, dan zult u 108 00:06:15,690 --> 00:06:17,080 net een rode smiley. 109 00:06:17,080 --> 00:06:20,380 Maar het nemen van een diepere duik in, we zullen zien dat de structuur 110 00:06:20,380 --> 00:06:22,340 van het is gewoon pixels. 111 00:06:22,340 --> 00:06:25,880 We hebben witte pixels, en dan de rode pixels. 112 00:06:25,880 --> 00:06:31,000 De witte, ffffff, en vervolgens alle rode pixels Ik heb ingekleurd 113 00:06:31,000 --> 00:06:35,440 hier, en je ziet dat ze 0000ff. 114 00:06:35,440 --> 00:06:39,760 Nul blauw, nul groen, en volle rode. 115 00:06:39,760 --> 00:06:45,350 En aangezien smiley is acht pixels breed, we hebben geen padding. 116 00:06:45,350 --> 00:06:47,360 Oke. 117 00:06:47,360 --> 00:06:53,310 >> Dus als ik verschillende waarden toekennen een RGBTRIPLE en ik wilde 118 00:06:53,310 --> 00:06:58,350 maken het groen, dan is wat ik zou doen is Ik zou een RGBTRIPLE, genaamd verklaren 119 00:06:58,350 --> 00:07:02,660 drievoud, en vervolgens elke toegang byte binnen deze structuur I 120 00:07:02,660 --> 00:07:04,030 zou de operator punt te gebruiken. 121 00:07:04,030 --> 00:07:08,430 Dus triple.rgbtBlue, ik kan toewijzen dat voor 0. 122 00:07:08,430 --> 00:07:13,460 Green I kan toewijzen aan volle - elke nummer, echt, tussen 0 en ff. 123 00:07:13,460 --> 00:07:15,470 En dan rood, ben ik ook gaan zeggen 0. 124 00:07:15,470 --> 00:07:19,160 Dus dan dat geeft me een groene pixel. 125 00:07:19,160 --> 00:07:23,030 >> Vervolgens, wat als ik wil controleren de waarde van iets? 126 00:07:23,030 --> 00:07:27,250 Ik kon iets dat de controles hebben of de triple's rgbtBlue waarde is 127 00:07:27,250 --> 00:07:31,080 ff en dan afdrukken, "Ik voel me blauw ", als resultaat. 128 00:07:31,080 --> 00:07:35,640 Nu, dat betekent niet noodzakelijkerwijs dat de pixel is blauw, toch? 129 00:07:35,640 --> 00:07:40,060 Omdat de pixel groene en rode waarden zou eveneens niet-0-waarden. 130 00:07:40,060 --> 00:07:43,470 Alles wat dit betekent, en dat alles dit is het controleren voor is 131 00:07:43,470 --> 00:07:45,610 voor een volledige blauwe kleur. 132 00:07:45,610 --> 00:07:50,050 Maar alle pixels kan ook gedeeltelijke kleurwaarden, zoals deze 133 00:07:50,050 --> 00:07:52,180 volgende voorbeeld hier. 134 00:07:52,180 --> 00:07:55,400 >> Het is een beetje moeilijker te zien wat dit beeld is nu. 135 00:07:55,400 --> 00:08:00,320 Dit ziet er een beetje meer op de clue.bmp dat je gegeven worden. 136 00:08:00,320 --> 00:08:03,600 Nu, fysiek, je zou dit op te lossen, omdat er veel rood, door 137 00:08:03,600 --> 00:08:07,040 houdt een rood scherm om het beeld zo dat de andere kleuren kunnen worden weergegeven. 138 00:08:07,040 --> 00:08:10,968 Dus hoe kunnen we nabootsen dit met c? 139 00:08:10,968 --> 00:08:15,640 Nou ja, kunnen we verwijder alle rood volledig uit het beeld. 140 00:08:15,640 --> 00:08:21,870 En zo te doen dat we elke zouden stellen roodwaarde pixel tot 0. 141 00:08:21,870 --> 00:08:25,020 En zo zou het beeld een beetje kijken beetje zoals dit, waar we hebben geen rode 142 00:08:25,020 --> 00:08:26,300 dan ook. 143 00:08:26,300 --> 00:08:29,390 >> We kunnen de verborgen boodschap een zien beetje meer nu duidelijk. 144 00:08:29,390 --> 00:08:31,730 Het is weer een smiley gezicht. 145 00:08:31,730 --> 00:08:33,870 Of misschien kunnen we een andere methode gebruiken. 146 00:08:33,870 --> 00:08:36,480 Misschien kunnen we identificeren alle rode pixels - 147 00:08:36,480 --> 00:08:41,100 dat wil zeggen alle pixels met 0 blauw, groen 0 en 0 rood - 148 00:08:41,100 --> 00:08:43,169 en verander die naar wit. 149 00:08:43,169 --> 00:08:45,470 En onze afbeelding ziet er misschien iets als dit. 150 00:08:45,470 --> 00:08:48,250 Een beetje makkelijker te zien. 151 00:08:48,250 --> 00:08:51,170 >> Er zijn veel andere manieren om te ontdekken de geheime boodschap ook, 152 00:08:51,170 --> 00:08:53,730 omgaan met de kleur manipulatie. 153 00:08:53,730 --> 00:08:57,050 Misschien heb je zou kunnen gebruiken een van de methoden die ik hierboven heb genoemd. 154 00:08:57,050 --> 00:08:59,600 En bovendien, wil je misschien sommige kleuren te verbeteren 155 00:08:59,600 --> 00:09:02,620 en brengen die uit. 156 00:09:02,620 --> 00:09:06,190 >> Dus nu dat we de pixel hebt veranderd kleur, volgende we hoeven alleen maar om ze te schrijven 157 00:09:06,190 --> 00:09:08,500 in de scanline, pixel voor pixel. 158 00:09:08,500 --> 00:09:11,860 En nog eens, wil je om terug te kijken naar copy.c, als je niet hebt gekopieerd 159 00:09:11,860 --> 00:09:18,170 het al, en kijk naar de fwrite functie, welke gegevens neemt, een pointer 160 00:09:18,170 --> 00:09:23,230 de structuur die de bytes bevat dat je het lezen van de omvang van 161 00:09:23,230 --> 00:09:26,610 de items, het aantal items, en vervolgens de outptr - 162 00:09:26,610 --> 00:09:29,450 de bestemming van die bestanden. 163 00:09:29,450 --> 00:09:34,010 >> Na het schrijven in de pixels, zul je ook te schrijven in de opvulling. 164 00:09:34,010 --> 00:09:34,970 Wat is padding? 165 00:09:34,970 --> 00:09:38,670 Nou, elke rgbt pixel drie bytes lang. 166 00:09:38,670 --> 00:09:43,670 Maar, het scanline voor een bitmapafbeelding moet een veelvoud van vier bytes. 167 00:09:43,670 --> 00:09:47,650 Als het aantal pixels is geen veelvoud van vier is, dan moeten we voegen 168 00:09:47,650 --> 00:09:48,880 deze padding. 169 00:09:48,880 --> 00:09:51,420 Padding is gewoon vertegenwoordigd door 0s. 170 00:09:51,420 --> 00:09:54,380 Dus, hoe kunnen we schrijven, of lezen dit? 171 00:09:54,380 --> 00:09:59,280 Nou, het blijkt dat je niet kunt eigenlijk fread padding, maar u kunt 172 00:09:59,280 --> 00:10:00,970 berekenen. 173 00:10:00,970 --> 00:10:04,400 >> In dit geval, de aanwijzing en de uitspraak dezelfde breedte, zodat de 174 00:10:04,400 --> 00:10:05,910 padding is hetzelfde. 175 00:10:05,910 --> 00:10:09,370 En de vulling, zoals u zult zien in copy.c, berekend 176 00:10:09,370 --> 00:10:11,790 met onderstaande formule - 177 00:10:11,790 --> 00:10:16,690 bi.biWidth tijden sizeof (RGBTRIPLE) zal geven ons hoeveel bytes de bmp 178 00:10:16,690 --> 00:10:18,280 heeft in elke rij. 179 00:10:18,280 --> 00:10:21,890 Van daar, de modulos en aftrekkingen met 4 kan berekenen hoe 180 00:10:21,890 --> 00:10:25,610 vele bytes worden toegevoegd zodat de veelvoud van bytes op 181 00:10:25,610 --> 00:10:27,250 elke rij vier. 182 00:10:27,250 --> 00:10:30,490 >> Nu dat we de formule voor hoeveel padding we nodig hebben, nu 183 00:10:30,490 --> 00:10:31,610 kunnen we het schrijven. 184 00:10:31,610 --> 00:10:34,080 Nu, ik eerder al noemde, padding is gewoon 0s. 185 00:10:34,080 --> 00:10:39,730 Dus in dat geval, we zomaar een char, in dit geval een 0, in onze 186 00:10:39,730 --> 00:10:41,710 outptr - onze outfile. 187 00:10:41,710 --> 00:10:47,530 Dus dat kan gewoon fputc zijn 0, komma outptr. 188 00:10:47,530 --> 00:10:52,400 >> Dus, terwijl we al lezen in onze bestand, heeft het dossier van I / O-spoor van hielden onze 189 00:10:52,400 --> 00:10:57,440 positie in die bestanden met iets riep het bestand positie-indicator. 190 00:10:57,440 --> 00:10:59,350 Zie het als een cursor. 191 00:10:59,350 --> 00:11:03,550 Kortom, het vooruit elke keer dat we fread, maar we hebben 192 00:11:03,550 --> 00:11:05,671 controle over het ook. 193 00:11:05,671 --> 00:11:11,030 >> Om het bestand positie-indicator verplaatsen, kunt u de functie fseek gebruiken. 194 00:11:11,030 --> 00:11:15,600 Wanneer de inptr voor de bestandsnaam pointer die je zoekt in, de 195 00:11:15,600 --> 00:11:20,370 bedrag is het aantal bytes dat u de cursor wilt verplaatsen, en vervolgens uit 196 00:11:20,370 --> 00:11:23,470 betrekking op het referentiepunt van waar de cursor is. 197 00:11:23,470 --> 00:11:26,770 Als je pas in SEEK_CUR, dat vertegenwoordigt de huidige 198 00:11:26,770 --> 00:11:28,100 positie in het bestand. 199 00:11:28,100 --> 00:11:31,020 Of u kunt gebruik maken van een aantal andere parameters. 200 00:11:31,020 --> 00:11:35,400 Dus, zouden we willen fseek gebruiken om over te slaan over de opvulling van de in het dossier. 201 00:11:35,400 --> 00:11:39,410 En nogmaals, als je vastzit, is er een voorbeeld van die in copy.c. 202 00:11:39,410 --> 00:11:43,260 >> Dus nu hebben we het bestand geopend, de aanwijzing, en het vonnis. 203 00:11:43,260 --> 00:11:46,450 We hebben de header info voor bijgewerkte ons oordeel, omdat elke 204 00:11:46,450 --> 00:11:48,730 bitmap moet een header. 205 00:11:48,730 --> 00:11:52,280 We hebben dan te lezen in de aanwijzing van scanline, pixel voor pixel, veranderen 206 00:11:52,280 --> 00:11:55,210 elke kleur nodig en het schrijven van die in de 207 00:11:55,210 --> 00:11:57,340 vonnis, pixel voor pixel. 208 00:11:57,340 --> 00:12:01,550 Zodra je uitspraak opent, kunt u zien wie de dader, of wat het geheim 209 00:12:01,550 --> 00:12:02,850 boodschap is. 210 00:12:02,850 --> 00:12:05,550 Mijn naam is Zamyla, en dit was whodunit. 211 00:12:05,550 --> 00:12:12,864