[Powered by Google Translate] [Walk Through - Probleem Set 4] [Zamyla Chan - Harvard Universiteit] [Hierdie is CS50. - CS50.TV] Alles reg. Hallo, almal, en welkom by Walk Through 4. Vandag ons pset is Forensics. Forensics is 'n baie pret pset wat die volgende behels die hantering van bitmap lêers om te ontdek wat 'n misdaad gepleeg het. Daarna het ons gaan 'n bitmap lêers om te verander, dan is ons ook gaan om te gaan met 'n baie pret deel genoem Herstel, wat ons is basies 'n geheue kaart ingehandig wat iemand per ongeluk geskrap al hulle lêers, en ons is gevra om die lêers te herstel. Maar eers, voor ons in die pset kry, ek regtig wil net almal geluk te wens. Ons is op die punt om by die middelpunt van hierdie kursus. Quiz 0 is agter ons, en ons is op pset4, so in wese, het ons halfpad is. Ons het 'n lang pad as jy terugkyk na jou psets, pset0 en pset1, so gelukwens jouself oor wat, en ons gaan om te kry in 'n paar regtig fun stuff. So ons toolbox vir hierdie pset, weer, in plaas van die bestuur van sudo yum-y update, ons is in staat om net hardloop update50 as jy by weergawe 17,3 en bo van die toestel. So seker wees update50 uit te voer - dit is 'n baie makliker, 'n paar minder karakters - om seker te maak dat jy die nuutste weergawe van die toestel. Dit is veral belangrik om te update50 wanneer ons begin met behulp van CS50 Check. So maak seker dat jy dit doen. Vir al die afdelings vir hierdie pset, ons gaan doen met lêer insette en uitsette, lêer I / O. Ons gaan om te gaan oor 'n klomp van programme wat hanteer skikkings verwys na lêers en dinge soos wat, sodat ons wil hê om seker te maak dat ons regtig vertroud en gemaklik wat handel oor hoe om te inset en uitset in lêers. In die verspreiding kode vir hierdie pset is 'n lêer genaamd copy.c, en dit is wat ons gaan om uit te vind is gaan om te wees regtig nuttig vir ons want ons gaan eindig eintlik die kopiëring van die copy.c lêer en net verander dit effens in staat te wees om die eerste 2 dele van die probleem stel te bereik. En so is daar dan soos ek voorheen genoem, is ons handel met bitmaps sowel as JPEG. So regtig begrip van die struktuur van hoe dié lêers georganiseer, hoe ons werklik kan vertaal die 0'e en 1s in structs en dinge dat ons werklik kan verstaan ​​en te interpreteer, wysig, wat werklik belangrik sal wees, so gaan in JPEG en bitmap lêers en begrip van die struktuur van daardie. Pset4, soos gewoonlik, begin met 'n gedeelte van die vrae. Diegene sal hanteer lêer I / O en jy gewoond aan. Dan deel 1 is detective verhaal, waarin jy 'n bitmap-lêer is gegee wat lyk soort van soos rooi kolletjies oral oor. En dan basies wat ons gaan doen is om hierdie lêer en dit verander net effens in 'n weergawe wat ons kan lees. Wese, sodra ons klaar is, sal ons dieselfde lêer, behalwe ons sal in staat wees om die verborge boodskap te sien wat verborge is deur al die rooi kolle. Dan Resize is 'n program dat, gegewe 'n lêer en dan die naam van die lêer wat dit uitgange en dan 'n aantal so goed, sal werklik die grootte van daardie bitmap deur daardie heelgetalwaarde. Dan laastens, ons het van die vergete pset. Ons kry 'n geheue kaart en dan het al die foto's om te herstel wat per ongeluk geskrap is, Maar, soos ons sal leer, nie eintlik verwyder en verwyder uit die lêer; ons net soort van verlore waar hulle was in die lêer nie, maar ons gaan om te herstel. Groot. So gaan in lêer I / O spesifiek, dit is 'n hele lys van funksies wat jy sal gebruik word. Jy het reeds 'n bietjie gesien die basiese beginsels van die fopen, fread en fwrite, maar ons gaan om verder te kyk na 'n paar lêer I / O funksies soos fputc, wat jy net skryf 'n karakter op 'n tyd, fseek, waar jy soort van die lêer posisie aanwyser beweeg vorentoe en agtertoe, en dan 'n paar ander. Maar ons gaan in dat 'n bietjie later gedurende die pset. So die eerste, om net in die lêer I / O voordat ons gaan in die pset, 'n lêer oop te maak, byvoorbeeld, is eintlik wat jy hoef te doen 'n wyser na daardie lêer. So ons het 'n lêer * wyser. In hierdie geval, ek noem dit 'n wyser, want dit gaan my infile. En so gaan ek die funksie fopen en dan die naam van die lêer te gebruik en dan die wyse waarop ek gaan te doen het met die lêer. So daar is "r" in hierdie geval vir lees, "w" oopmaak vir skryf, en dan 'n "" vir die aanbring. Byvoorbeeld, wanneer jy te doen het met 'n infile en al wat jy wil doen is lees die bits en bytes wat daar gestoor word, dan is jy waarskynlik gaan om te wil "r" as jou modus te gebruik. As jy wil om werklik te skryf, soort van 'n nuwe lêer, dan wat ons gaan doen, is ons gaan die nuwe lêer oop te maak en gebruik die "W"-modus vir skryf. So dan wanneer jy eintlik lees in die lêers, die struktuur is as volg. Die eerste wat jy sluit in die wyser na die struct wat die grepe wat jy lees sal bevat. So wat gaan aan die einde ligging van die grepe wat jy lees. Jy dan gaan om die grootte aan te dui, soos basies hoeveel bytes jou program het te lees in die lêer, die grootte basies een element is, en dan moet jy gaan om te spesifiseer hoeveel elemente wat jy wil lees. En dan uiteindelik, moet jy weet waar jy die lees van, so wat gaan jou in wyser wees. Ek kleur-gekodeer hierdie omdat fread is ook baie soortgelyk aan fwrite, behalwe as jy wil om seker te maak dat jy gebruik maak van die korrekte volgorde, maak seker dat jy eintlik wil skryf of lees van die regte lêer. So dan as voorheen, as ons die grootte van die element sowel as die aantal elemente, dan kan ons speel hier 'n bietjie. Sê ek het 'n hond struct en so dan wil ek twee honde op 'n keer te lees. Wat ek kan doen is die grootte van een element sê gaan na die grootte van 'n hond te wees en ek gaan om werklik te lees twee van hulle. Alternatiewelik, wat ek kon doen, sê ek net gaan om een ​​element te lees en dat een element is gaan om die grootte van die twee honde. So wat is analoog hoe jy kan soort van speel rond met die grootte en aantal afhangend op wat meer intuïtief aan jou is. Alles reg. So nou het ons kry om te skryf van lêers. As jy wil om 'n lêer te skryf, die eerste argument is eintlik waar jy die lees van. So wat is basies die data wat jy gaan skryf in die lêer, wat die uit wyser aan die einde. So wanneer jy die hantering met die pset, maak seker dat jy nie deurmekaar raak nie. Miskien het die definisies kant deur die kant. Jy kan trek die definisies in die handleiding deur te tik man en dan fwrite, byvoorbeeld, in die terminale, of jy kan verwys terug na hierdie slide en maak seker dat jy die regte een gebruik. So weer, vir fwrite, wanneer jy 'n lêer wat jy wil om te skryf in, wat gaan die laaste argument wees en dit gaan 'n wyser na daardie lêer. So dan is dit hoe ons omgaan met die skryf van miskien 'n paar grepe op 'n slag, maar sê jy wil om net te skryf in net een enkele karakter. Soos ons later sal sien, in hierdie voorbeeld, in die bitmaps ons sal hê om dit te gebruik. Dit is wanneer ons kan gebruik fputc, in wese net om een ​​karakter op 'n tyd, chromosoom, in die lêer pointer, en dit is ons uit wyser daar. So is dan wanneer ons soek of skryf in 'n lêer, die lêer dop van waar ons is. So dit is 'n soort van die muis, die lêer posisie aanwyser. En so wanneer ons lees of skryf nie weer in 'n lêer, die lêer onthou eintlik waar dit is, en so is dit steeds van waar die wyser is. Dit kan voordelig wees wanneer jy wil, sê, lees in 'n sekere bedrag om iets te doen en lees dan in die volgende bedrag, maar soms het ons dalk wil terug of eintlik die begin van 'n sekere verwysing waarde. So dan is die fseek funksie, wat dit doen, is stel ons in staat om die wyser om te beweeg in 'n bepaalde lêer 'n sekere aantal grepe. En dan wat ons hoef te doen is om te spesifiseer waar die verwysing waarde is. Dus of dit vorentoe of agtertoe beweeg waar die wyser tans is, of ons kan bepaal dat dit net van die begin van die lêer moet beweeg in of van die einde van die lêer. En sodat jy kan slaag in 'n negatiewe of positiewe waardes bedrag, en dat die soort van beweeg die muis óf vorentoe of agtertoe. Voordat ons in die ander psets, enige vrae oor lêer I / O? Okay. Soos ons kry in meer voorbeelde, voel vry om my te stop vir vrae. So in die detective verhaal, jy oorhandig 'n bitmap lêer soortgelyk aan die rooi een op die slide, en dit lyk soos hierdie - 'n klomp van die rooi kolletjies - en jy nie regtig weet wat geskryf. As jy squint, kan jy in staat wees om te sien 'n effense blouerige kleur binne-in die middel. Wese, dit is waar die teks gestoor word. Daar was 'n moord wat gebeur het, en wat ons nodig het om uit te vind wat dit gedoen het. Ten einde dit te doen, moet ons soort van hierdie beeld omskakel in 'n leesbare formaat. As julle ooit hierdie teëgekom word, soms is daar min kits waar jy wil hê 'n vergrootglas met 'n rooi film. Iemand? Ja. So jy sal oorhandig word iets soos hierdie, sou jy 'n vergrootglas met die rooi film oor dit, sou jy dit oor die beeld, en jy sal in staat wees om te sien die boodskap daarin weggesteek. Ons het nie 'n vergrootglas met rooi film, so plaas ons gaan soort van ons eie in hierdie pset. En so die gebruiker gaan insette detective verhaal, dan is die leidraad, bmp, so wat is die infile, wat is die rooi dot boodskap, en dan hulle sê verdict.bmp gaan ons outfile. So dit gaan 'n nuwe bitmap image soortgelyk aan die leidraad een te skep behalwe in 'n leesbare formaat waar ons kan sien die verborge boodskap. Aangesien ons gaan doen met die redigering en bitmaps van een of ander aard te manipuleer, ons gaan soort duik in die struktuur van hierdie bitmap lêers. Ons het oor hierdie 'n bietjie in die lesing, maar laat ons kyk na hulle 'n paar meer. Bitmaps is in wese net 'n rangskikking van bytes waar ons het gespesifiseer wat bytes beteken wat. So hier is soort van soos 'n kaart van die bitmapafbeelding sê dat dit begin met 'n paar header lêers, begin met 'n paar inligting in daar. Jy sien dat omstreeks byte nommer 14 die grootte is van die bitmapafbeelding aangedui, en dit gaan voort. Maar wat ons werklik geïnteresseerd is hier besig is om rondom byte nommer 54. Ons het hierdie RGB triples. Wat dit gaan doen, is die werklike pixels, die kleur waardes bevat. Alles bo in die kop is 'n paar inligting wat ooreenstem met die grootte van die beeld, die breedte van die beeld, en die hoogte. Wanneer gaan ons later in padding op, sal ons sien waarom die grootte van die beeld anders kan wees as die breedte of die hoogte. So dan voor te stel - hierdie bitmap beelde rye grepe - wat ons kan doen is om te sê okay, ek gaan om te onthou dat by indeks 14, dit is waar die grootte is, byvoorbeeld, maar eerder wat ons gaan doen om dit makliker te maak is kapselt dit in 'n struct. En so het ons twee structs vir ons gemaak, 'n BITMAPFILEHEADER en 'n BITMAPINFOHEADER, en so wanneer ons lees in daardie lêer, by verstek dit gaan om te gaan ten einde, en so ten einde dit gaan ook in te vul in veranderlikes soos biWidth en biSize. En dan uiteindelik, is elke pixel verteenwoordig deur drie grepe. Die eerste een is die bedrag van blou in die pixel, die tweede is die bedrag van groen, en uiteindelik, die bedrag van rooi, waar 0 is in wese geen blou of geen groen of geen rooi en dan ff is die maksimum waarde. Dit is hexadecimale waardes. Daarom dan, as ons het ff0000>, dan is wat ooreenstem met die maksimum bedrag van blou en dan geen groen en geen rooi, so dan nie wat jou sal gee ons 'n blou pixel. Dan as ons het ff se oor die hele raad, dan beteken dit dat ons het 'n wit pixel. Dit is 'n soort van teenoor tipies wanneer ons sê RGB. Dit is eintlik gaan BGR. So as ons eintlik kyk na 'n voorbeeld van 'n bitmap beeld - laat my toe een hier. Dit is 'n bietjie klein. Ek inzoomen, en ons kan sien dit is pixelated. Dit lyk soos blokke van kleur. Jy het 'n wit blokke en dan rooi blokke. As jy speel in Microsoft Paint, byvoorbeeld, kan jy maak iets soos dit deur basies net verf sekere blokkies in 'n spesifieke volgorde. So dan wat dit beteken in die bitmap is soos volg. Hier het ons eerste wit pixels, dat alle 6 f se, en dan het ons rooi pixels, aangedui deur 0000FF. En so het die volgorde van die grepe wat ons het dui aan hoe die bitmapafbeelding gaan om te kyk. So, wat ek hier gedoen het is net uitgeskryf al die grepe en dan bruin in die rooi sodat jy kan soort van sien, as jy squint 'n bietjie, hoe daardie soort dui op 'n smiley face. Die manier waarop bitmap beelde werk is ek visies dit basies as 'n rooster. En so by verstek, elke ry van die rooster het aan 'n veelvoud van 4 grepe. As ons kyk na 'n bitmap image, jy vul in elke waarde. Byvoorbeeld, kan jy 'n rooi hier, 'n groen hier, hier 'n blou, maar jy het om seker te maak dat die beeld is gevul met 'n veelvoud van vier grepe. So as ek wil my beeld te wees drie blokke wyd, dan sou ek 'n leë waarde te stel in die laaste een om te maak dit 'n veelvoud van vier. So, dan sou ek voeg in iets wat ons roep padding. Ek gaan net om aan te dui dat daar met 'n x. Nou sê ons wil 'n beeld wat 7 pixels lank is, byvoorbeeld. Ons het 1, 2, 3, 4, 5, 6, 7, en al wat is gevul met kleur. Die manier waarop bitmap beelde werk is dat ons 'n 8ste. Reg nou is ons het 1, 2, 3, 4, 5, 6, 7. Ons moet 8 ruimtes vir die bitmap beeld te korrek te lees. So dan wat ons hoef te doen is voeg in net 'n bietjie van die padding om seker te maak dat al die breedtes is uniform en dat al die breedtes is 'n veelvoud van 4. En so het ek voorheen aangedui, padding as 'n x of 'n kronkel lyn, maar in die werklike bitmap beelde die padding word aangedui deur 'n heksadesimale 0. So, wat sou 'n enkele karakter, 0 wees. Wat kan handig te pas kom in die xxd opdrag. Wat beteken dit eintlik wys jy, soos soortgelyk aan wat ek gedoen het voordat met die smiley wanneer ek eintlik gedruk wat elke kleur sou wees vir die pixel en dan kleur-gekodeer, wanneer jy loop xxd met die volgende opdragte, dan sal dit werklik druk wat die kleure is vir diegene pixels. Wat jy hoef te doen, is ek hier aandui, soos die-s 54 sê dat ek gaan om te begin by die 54ste byte want voor dit, onthou as ons terug kyk na die kaart van die bitmaps, dis al wat die header information en dinge soos dat. Maar wat ons regtig omgee, is die werklike pixels wat dui op die kleur. So deur die toevoeging in daardie vlag,-s 54, dan is ons in staat om die kleur waardes te sien. En moenie bekommerd wees oor die ingewikkelde vlae en dinge soos dat. In die probleem stel spec, sal jy aanwysings oor hoe om te gebruik xxd die pixels te vertoon. So as jy hier sien, lyk dit soort van soos 'n groen boks, hierdie klein ding. Ek het kleur-gekodeer die 00FF00 as basies sê geen blou, 'n baie van groen, en geen rooi. So wat ooreenstem met groen. As wat jy hier sien, sien ons 'n groen reghoek. Hierdie groen reghoek is slegs 3 pixels wyd, so dan wat ons hoef te doen om seker te maak dat die beeld is 'n veelvoud van 4 breed voeg in 'n ekstra padding. En so dan is dit hoe jy hierdie 0'e sien hier. Dit sal eintlik die gevolg van jou Resize pset, hoofsaaklik om die klein bitmap en dan die uitbreiding van dit deur 4. En so wat ons sien is dat eintlik hierdie beeld is 12 pixels wyd, maar 12 is 'n veelvoud van 4, en so het ons eintlik sien nie enige 0'e aan die einde, want ons hoef nie by te voeg want dit is ten volle opgestopte. Dit hoef nie 'n meer ruimte. Okay. Enige vrae oor padding? Okay. Cool. Soos ek voorheen genoem, die bitmaps is net 'n reeks van grepe. En wat ons het, is in plaas van nodig om tred te hou van presies watter aantal byte ooreenstem met 'n spesifieke element, ons eintlik 'n struct om dit te stel. So, wat ons het is 'n RGBTRIPLE struct. Wanneer jy 'n voorbeeld van 'n RGB triple, want dit is 'n tipe definieer struct, dan kan jy toegang tot die rgbtBlue veranderlike, insgelyks die groen en rooi veranderlikes, wat sal aandui hoeveel blou, groen en rooi, onderskeidelik, wat jy het. So indien ons het die blou veranderlike stel tot 0, die groen stel ff wat is die maksimum waarde wat jy kan hê, en dan die rooi veranderlike ingestel op 0, dan watter kleur sou hierdie spesifieke RGB triple verteenwoordig? >> [Student] Green. Green. Presies. Dit gaan nuttig wees om te weet dat wanneer jy 'n voorbeeld van 'n RGB triple, jy kan eintlik toegang tot die bedrag van kleur - blou, groen en rooi - afsonderlik. Nou dat ons het gepraat oor die struktuur van die, kom ons neem 'n blik op die BMP-lêer. Dit is structs vir jou gemaak. Hier het ons het 'n BITMAPFILEHEADER struct. Van belang is die grootte. Later, het ons die info kop, wat het 'n paar dinge wat interessant is vir ons, naamlik die grootte, die breedte en die hoogte. Soos ons gaan in later, wanneer jy lees in die lêer, dit lees outomaties in, want ons het die bevel om dieselfde te wees. So die biSize sal die regte bytes wat ooreenstem met die werklike grootte van die beeld. En dan hier, laastens, as ons het gepraat oor, het ons die RGBTRIPLE typedef struct. Ons het 'n rgbtBlue, Green, en Red wat verband hou met dit. Groot. Okay. Nou dat ons verstaan ​​bitmaps 'n bietjie, verstaan ​​dat ons 'n lêer header en 'n info header wat verband hou met dit en dan na daardie, ons het die interessante dinge van die kleure en die kleure verteenwoordig deur RGBTRIPLE structs, en diegene wat, op sy beurt, het drie waardes verbonde aan die blou, die groen en die rooi. So, nou, kan ons soort Herstel dink 'n bietjie. Jammer. Dink oor die detective verhaal. Wanneer ons ons leidraad lêer, dan wat ons wil doen, is om dit te lees in pixel vir pixel en dan een of ander manier daardie pixels verander sodat ons dit kan uitvoer in 'n leesbare formaat. En so het dit tot uitvoer, ons gaan pixel pixel in die verdict.bmp lêer te skryf. Dit is soort van 'n baie om te doen. Ons besef dat. So wat ons gedoen het is ons eintlik het op voorwaarde dat jy met copy.c. Wat copy.c doen is net maak 'n presiese kopie van 'n gegewe bitmap lêer en dan uitgange dit. So dit open reeds die lêer vir jou, lees pixel vir pixel, en skryf dit dan in 'n uitvoer lêer. Kom ons neem 'n blik op dit. Dit is om te verseker behoorlike gebruik, om die lêername hier. Wat dit beteken is dit stel die invoer lêer om te wees wat ons het geslaag in die infile hier, wat ons tweede opdrag-lyn argument. Kontroleer om seker te maak dat ons die lêer kan oopmaak. Kontroleer om seker te maak ons ​​kan 'n nuwe outfile hier. Dan wat dit hier doen, is dit net begin basies lees van die begin af aan die bitmap lêer. Die begin, soos ons weet, bevat die BITMAPFILEHEADER, en so daardie rye bisse sal direk vul in die BITMAPFILEHEADER. So, wat het ons hier sê dat BITMAPFILEHEADER bf - dit is ons nuwe veranderlike van tipe BITMAPFILEHEADER - ons gaan sit binne bf wat ons lees in wyser, wat ons infile. Hoeveel lees ons? Ons lees in hoeveel bytes ons die hele BITMAPFILEHEADER nodig te bevat. Net so, dit is wat ons doen vir die info kop. Sodat ons verder in ons lêer in die infile, en ons is die lees van die bits en bytes en ons steek hulle direk in in hierdie gevalle van die veranderlikes wat ons maak. Hier is ons net om seker te maak dat die bitmap is 'n bitmap. Nou het ons 'n outfile, reg? So as dit staan, wanneer ons dit geskep het, dit is in wese leeg. So ons moet basies 'n nuwe bitmap van nuuts af skep. Wat ons doen is ons het om seker te maak dat ons in die lêer header kopieer en die info bladsyboskrif ('header') net soos die infile. Wat ons doen is ons skryf - en onthou dat bf is die veranderlike van die tipe BITMAPFILEHEADER, so wat ons doen is ons net gebruik om die inhoud om te skryf in die outfile. Hier, onthou ons het gepraat oor padding, hoe dit is belangrik om seker te maak dat die bedrag van pixels wat ons het is 'n veelvoud van 4. Dit is 'n redelik bruikbare formule om te bereken hoeveel padding jy gegewe die breedte van jou lêer. Ek wil julle ouens om te onthou dat in copy.c ons het 'n formule vir die berekening van die padding. Okay? Sodat almal onthou dat. Groot. So dan wat copy.c doen volgende is dit iterate oor al die horisontale skandeerlyne. Dit gaan eers deur die rye en dan slaan elke triple wat dit lees en skryf dit dan in die outfile. So, hier is ons die lees van slegs een RGB triple op 'n tyd en dan om dieselfde triple na die outfile. Die moeilike deel is dat die padding nie is 'n RGB triple, en daarom kan ons nie net gelees dat padding bedrag van RGB triples. Wat ons moet doen is eintlik net ons lêer posisie aanwyser beweeg, beweeg ons wyser, soort slaan oor al die padding sodat ons by die volgende ry. En is dan wat dit doen afskrif wys jou hoe jy wil dalk die padding te voeg. Dus het ons bereken hoeveel padding wat ons nodig het, so dit beteken dat ons moet padding aantal van 0e. Wat dit beteken is 'n lus wat sit padding aantal 0'e in ons outfile. En dan uiteindelik, jy sluit beide lêers. Jy sluit die infile sowel as die outfile. So dit is hoe copy.c werke, en dit gaan baie handig wees. In plaas van net eintlik direk kopieer en plak dit of net op soek na dit en tik in wat jy wil, jy dalk net wil om hierdie opdrag uit te voer in die terminale, cp copy.c whodunit.c, wat sal 'n nuwe lêer te skep, whodunit.c, wat bevat presies dieselfde inhoud as die kopie nie. So dan wat ons kan doen is die gebruik dat as 'n raamwerk om op te bou en te wysig vir ons detective verhaal lêer. Dit is ons tot-dos te doen vir detective verhaal, maar wat copy.c doen is eintlik neem sorg van die meeste van hulle vir ons. So al wat ons nodig het om volgende te doen, is die pixels verander as dit nodig is om werklik te maak die lêer leesbaar. Onthou dat vir 'n gegewe pixel triple, so vir 'n gegewe veranderlike van tipe RGBTRIPLE, kan jy toegang tot die blou, groen, rooi en waardes. Wat gaan handig te pas kom, want as jy hulle kan toegang tot, wat beteken dat jy kan ook check hulle, en dit beteken dat jy kan ook verander hulle. So wanneer ons gaan terug na ons rooi vergrootglas voorbeeld, basies, is wat optree as 'n soort van filter vir ons. So, wat ons wil doen, is wat ons wil al van die drietalle wat inkom te filter Daar is verskillende maniere om dit te doen. Basies, kan jy watter tipe filter wat jy wil. Miskien wil jy al die rooi pixels te verander of dalk wil jy 'n ander kleur pixel te verander na 'n ander kleur. Dit is aan jou. Onthou dat jy kan sien watter kleur die pixel is en dan kan jy ook verander dit as jy gaan deur. Okay. So dit is detective verhaal. Sodra jy hardloop detective verhaal, sal jy weet wie die skuldige van die misdaad was. Nou het ons gaan om te gaan om grootte aan te pas. Ons gaan om nog te doen het met bitmaps. Wat ons gaan doen, ons gaan 'n inset bitmap te hê en dan gaan ons in 'n getal en dan kry 'n outfile bitmap waar dit is basies ons infile afgeskaal deur n. Sê my lêer is net 'n pixel groot. En as my n 3, skalering deur 3, dan sou ek dat pixel n aantal kere herhaal, so 3 keer, en dan ook skaal dit af 3 keer so goed. So jy sien ek dit is skalering vertikaal sowel as horisontaal. En dan is hier is 'n voorbeeld. As jy 'n = 2, sien jy dat die eerste blou pixel is daar twee keer herhaal horisontaal sowel as twee keer vertikaal. En dan is dit nog steeds op, en sodat jy het 'n direkte skalering van jou oorspronklike beeld deur twee. Daarom dan, as ons aan detail die pseudokode vir hierdie, ons wil om die lêer oop te maak. En dan weet dat as ons terug gaan hier, sien ons dat die breedte vir die outfile gaan om anders te wees as die wydte van die infile. Wat beteken dit? Dit beteken dat ons header information gaan verander. En wat ons sal wil doen is werk die header info, weet dat wanneer ons lees in die lêers as jy op die copy.c raamwerk, ons het reeds 'n veranderlike wat aandui wat die grootte is en dinge soos dat. So wanneer jy dit gedoen het, wat jy dalk wil om dit te doen is om daardie spesifieke veranderlikes te verander. Onthou, as jy het 'n struct, hoe jy toegang tot die veranderlikes binne daardie. Jy gebruik die dot-operateur, reg? So dan met behulp van dat, jy weet wat jy nodig het om te verander die header info. So hier is net 'n lys van die werklike elemente wat gaan verander in jou lêer. Die lêer grootte gaan word verander, die beeld, sowel as die breedte en die hoogte. So dan terug te gaan na die kaart van die bitmaps, kyk of dit is die lêer kop-of die info header wat die inligting bevat en dan verander soos nodig. Weereens, sê cp copy.c resize.c. Dit beteken dat resize.c bevat alles wat binne afskrif omdat afskrif bied ons 'n manier van lees in elke scanline pixel pixel. Behalwe nou, in plaas van net die verandering van die waardes soos ons gedoen het in detective verhaal, wat ons wil doen, is wat ons wil om te skryf in verskeie pixels so lank as wat ons n groter as 1 is. Dan wat ons wil doen, is wat ons wil om dit te horisontaal strek deur n, sowel as dit vertikaal deur n rek. Hoe kan ons dit doen? Sê jou n 2 is, en jy het dit gegee infile. Jou cursor is gaan om te begin op die eerste een, en wat jy wil om dit te doen as n 2, wil jy te druk in 2 van daardie. So jy druk in 2 van daardie. Dan jou muis gaan om te skuif na die volgende pixel, wat is die rooi een, en dit gaan uit te druk 2 van daardie rooies, aanbring dit op wat dit voorheen gedoen. Toe het die wyser beweeg na die volgende pixel en trek in 2 van daardie. As jy kyk terug na die copy.c raamwerk, wat dit doen reg hier dit skep 'n nuwe geval van 'n RGB triple, 'n nuwe veranderlike genoem triple. En hier wanneer dit daarin lees, is dit van die infile 1 RGBTRIPLE lees en stoor dit binnekant van daardie triple veranderlike. So dan is jy eintlik 'n veranderlike wat daardie spesifieke pixel. Dan wanneer jy skryf, wat jy dalk wil om dit te doen, is omsluiten die fwrite verklaring in 'n for-lus wat skryf dit in jou outfile soveel keer as wat nodig is. Dit is eenvoudig genoeg. Net basies die skryfproses n aantal kere wat dit horisontaal skaal herhaal. Maar dan moet ons onthou dat ons padding gaan verander. Voorheen, sê ons het iets van lengte 3. Dan sou ons voeg net in hoeveel padding? Nog net een te maak dit 'n veelvoud van 4. Sê dit maar met ons hierdie besondere beeld skalering deur n = 2. So, hoe baie blou pixels sal ons aan die einde? Ons wil hê 6. 1, 2, 3, 4, 5, 6. Alles reg. 6 is nie 'n veelvoud van 4. Wat is die naaste veelvoud van 4? Wat gaan wees 8. So ons is eintlik 2 karakters van padding daar te hê. Nie almal onthou as ons 'n formule te bereken padding en waar dit kan wees? [Onhoorbaar student reaksie] >> Ja, copy.c. Reg. Daar is 'n formule in copy.c om te bereken hoeveel padding jy gegewe 'n spesifieke breedte van die bitmapafbeelding. So is daar dan wat gaan nuttig wees wanneer jy dit nodig om by te voeg in 'n sekere bedrag van die padding om werklik uit te vind hoe veel tyd wat jy nodig het om by te voeg. Maar een noot, al is, is dat jy wil om seker te maak dat jy die regte grootte gebruik. Net versigtig wees want jy basies gaan word wat met twee bitmap beelde. Jy wil om seker te maak dat jy die regte een gebruik. Wanneer jy die padding is bereken vir die outfile, jy wil die breedte van die outfile te gebruik en die breedte van die vorige een nie. Groot. Daardie soort van sorg van die strekking van 'n hele bitmap image horisontaal. Maar wat ons wil doen, is dit eintlik strek vertikaal sowel. Dit gaan 'n bietjie moeiliker te wees want as ons klaar is die kopiëring van 'n ry en die skryf van die ry, word ons wyser aan die einde gaan wees. So as ons lees weer, dan is dit net gaan om na die volgende lyn te lees. So, wat ons wil doen, is soort van 'n paar van die kopiëring van die rye weer of net soort van die neem van die ry en dan herskryf dit weer. As ek soort van verwys na, daar is verskillende maniere om dit te doen. Wat jy kan doen is as jy gaan deur en lees deur die betrokke scanline en om dit te verander as wat nodig is, dan soort van winkel al van daardie pixels in 'n skikking. Dan later op jou weet wat jy nodig het om uit te druk dat die skikking weer, en so kan jy net gebruik dat array om dit te doen. Nog 'n manier om dit te doen wat jy kan kopieer een ry, verstaan ​​wat jy nodig het om dit weer te kopieer, so eintlik beweeg jou muis, en wat gaan word met behulp van die metode fseek. Jy kan jou muis beweeg al die pad terug en dan die kopieer proses weer herhaal. So as ons skalering nommer is n, dan hoeveel keer sal ons om terug te gaan en herskryf 'n lyn? >> [Student] n - 1. >> Ja, volmaak. n - 1. Ons het dit een keer al gedoen, so dan sal ons wil gaan terug proses te herhaal n - 1 bedrag van die tye. Okay. So daar het jy jou resize funksie. Nou kan ons kry om 'n baie pret deel, my gunsteling pset, wat Herstel. In plaas van bitmaps, hierdie keer het ons te doen met JPEG. Ons is eintlik nie 'n lêer net van JPEG, ons is basies 'n rou formaat geheugenkaart. En so gaan dit bevat 'n bietjie van die info en vullis waardes in die begin, en dan is dit begin en dit het 'n klomp van JPEG-lêers. Egter, is ons oorhandig 'n kaart waar ons die foto's verwyder; in wese, het ons vergeet waar die foto's is geleë binne die kaart. So dan is ons taak in Herstel is om te gaan deur middel van hierdie kaart formaat en vind die foto's weer. Gelukkig, die struktuur van JPEG-lêers en die kaart lêer is 'n bietjie nuttig. Dit kan beslis 'n bietjie moeiliker gewees het as dit nie in hierdie spesifieke formaat. Elke JPEG-lêer begin eintlik met twee moontlike rye, hierbo gelys. Basies, wanneer jy 'n nuwe JPEG-lêer, dit begin met die volgorde ffd8 ffe0 of die ander een, ffd8 ffe1. Nog 'n nuttige ding om te weet is dat JPEG contiguously gestoor. So wanneer een JPEG lêer eindig, die ander een begin. So daar is nie enige soort van in-tussen waardes daar. Sodra jy druk op die begin van 'n JPEG, as jy reeds die lees van 'n JPEG, jy weet dat jy die einde van die vorige een en die begin van die volgende een het getref. Soort van visualiseer dit, ek het 'n skematiese voorstelling. Nog 'n ding oor JPEG is dat ons hulle in rye van 512 bytes kan lees op 'n tyd, insgelyks met die begin van die kaart. Ons hoef nie te wees die kontrolering van elke enkele byte want dit sou suig. So in plaas, wat ons kan doen is eintlik net lees in 512 grepe op 'n slag en dan, in plaas van kontrole tussen diegene in daardie klein snye, ons kan net so die begin van die 512 bytes. Wese, in hierdie prent, wat jy sien is in die begin van die kaart, jy het waardes wat nie regtig relevant is vir die werklike JPEG self. Maar wat ek het, is 'n ster aan te dui een van die twee begin reekse vir 'n JPEG. So wanneer jy 'n ster sien, weet jy dat jy 'n JPEG-lêer. En dan elke JPEG-lêer gaan tot 'n veelvoud van 512 bytes maar nie noodwendig dieselfde veelvoud. Die manier waarop jy weet dat jy 'n ander JPEG het getref is as jy teen 'n ander ster, n ander volgorde grepe. Dan wat jy hier is dat jy die rooi JPEG-lêer voortgaan totdat jy 'n ster getref het, wat aangedui word deur 'n nuwe kleur. Jy voortgaan en dan kan jy die ander ster getref, jy getref 'n ander JPEG, jy nog steeds al die pad tot die einde toe. Jy op die laaste prentjie hier, die pienk een. Jy gaan tot die einde toe totdat jy getref die einde van die lêer karakter. Dit gaan werklik nuttig te wees. 'N Paar wegneemetes hier: Die kaart lêer nie begin met 'n JPEG, maar sodra 'n JPEG begin, is almal van die JPEG gestoor langs mekaar. Sommige pseudokode vir die Herstel. Eerste, gaan ons ons kaart lêer oop te maak, en wat gaan word deur gebruik te maak van ons lêer I / O-funksies. Ons gaan die volgende proses te herhaal totdat ons het aan die einde van die lêer. Ons gaan 512 grepe op 'n slag te lees. En wat ek hier gesê het, is ons gaan dit in 'n buffer te stoor, so basies hou op die 512 bytes totdat ons presies weet wat om te doen met hulle. Dan wat ons wil doen, is wat ons wil om te kyk of ons 'n ster of nie getref het. As ons 'n ster getref het, as ons het een van die beginspan rye getref, dan weet ons dat ons 'n nuwe JPEG-lêer het getref. Wat sal ons wil doen, is ons gaan om te wil 'n nuwe lêer te skep in ons pset4 directory om voort te gaan om daardie lêer. Maar ook as ons het reeds 'n JPEG voor, dan wil ons dat die lêer te beëindig en dit stoot aan die pset4 gids, waar ons sal hê om die lêer gestoor, want as ons spesifiseer nie dat ons wat JPEG-lêer het geëindig, dan sal ons basies 'n onbepaalde bedrag. Die JPEG sal nooit 'n einde. Sodat ons wil hê om seker te maak dat wanneer ons na 'n JPEG-lêer te lees en skryf dat, ons wil om spesifiek te sluit ten einde die volgende een oop te maak. Ons sal wil hê om seker te maak van verskeie dinge. Ons wil om te kyk of ons aan die begin van 'n nuwe JPEG met ons buffer en ook as ons reeds gevind het 'n JPEG voor want dit sal vir jou 'n proses effens verander. So dan nadat jy gaan deur al die pad en jy druk op die einde van die lêer, dan wat jy sal wil hê om dit te doen, is wat jy sal wil hê dat al die lêers wat tans oop te sluit. Dit sal waarskynlik die laaste JPEG-lêer wat jy het, sowel as die kaart lêer wat jy is besig met. Die laaste struikelblok wat ons nodig het om aan te pak, is hoe om werklik 'n JPEG-lêer en hoe om werklik te stoot dit na die gids. Die pset vereis dat elke JPEG wat jy vind in die volgende formaat wees, waar jy die nommer. jpg. Die getal, selfs al is dit 0, noem ons dit 000.jpg. Wanneer jy 'n JPEG in jou program, jy gaan om te wil om dit te noem in die volgorde waarin dit gevind. Wat beteken dit? Ons moet soort hou van hoeveel ons het gevind en wat die getal van elke JPEG behoort te wees. Hier het ons gaan om voordeel te trek van die funksie sprintf. Soortgelyk aan printf, wat net soort van afdrukke 'n waarde in die terminale, sprintf druk die lêer in die gids. En wat dit sou doen as ek het sprintf, titel, en dan die tou daar, dit sou druk 2.jpg. Die veronderstelling dat ek my lêers korrek gesluit het, wat sou bevat die lêer wat ek het uitskryf. Maar een ding is dat die kode wat ek hier nie heeltemal voldoen aan wat die pset vereis. Die pset vereis dat die tweede JPEG-lêer in plaas van net 2 002 moet genoem word. So wanneer jy die naam uit te druk, dan miskien is jy dalk wil die plaatsaanduiding effens verander. Nie almal onthou hoe ons voorsiening te maak vir 'n ekstra spasies wanneer ons iets druk? Ja. >> [Student] Jy het 'n 3 tussen die procent teken en die 2. >> Ja, volmaak. Jy sit 'n 3 in hierdie geval, want ons wil ruimte vir 3. % 3d sal waarskynlik gee jou 002.jpg in plaas van 2. Die eerste argument in die sprintf funksie is eintlik 'n char verskeidenheid, wat ons voorheen geweet het as stringe. Diegene wil, soort van meer soos 'n tydelike berging, net die stoor van die resulterende string. Jy sal regtig nie om met hierdie, maar wat jy nodig het om dit in te sluit. Die wete dat elke lêernaam het die getal, wat neem drie karakters, en dan jpg, hoe lank moet hierdie verskeidenheid? Gooi uit 'n aantal. Hoeveel karakters in die titel, in die naam? So daar is 3 hashtags, tydperk, jpg. >> [Student] 7. >> 7. Nie heeltemal nie. Ons gaan 8 te wil, want ons wil om voorsiening te maak vir die null-terminator as goed. Ten slotte, om net te trek uit die proses wat jy sal moet doen vir Herstel, jy het 'n paar begin inligting. Jy voortgaan totdat jy die begin van 'n JPEG-lêer, en dit kan een van twee begin rye. Jy hou op lees. Elke streep hier verteenwoordig 512 bytes. Jy hou aan lees, hou op lees totdat jy teëkom 'n ander begin ry. Sodra jy dat jy die einde van die huidige JPEG - in hierdie geval, dit is die rooi een, so jy wil dat aan die einde. Jy wil sprintf die naam van daardie in jou pset4-lêergids, dan is jy 'n nuwe JPEG oop te maak en dan hou op die lees van totdat jy die volgende teëkom. Hou op lees, hou op lees, en dan uiteindelik, uiteindelik, jy gaan die einde van die lêer te bereik, en so sal jy wil die laaste JPEG te sluit dat jy die werk met, sprintf dat in jou pset4-lêergids, en dan kyk na al die foto's wat jy gekry het. Hierdie foto's is eintlik foto's van CS50 personeel, en so is dit waar die bonus pret deel van die pset kom in is dat jy in jou afdelings meeding die TFS in die foto's te vind en neem foto's saam met hulle om te bewys dat jy die pset gedoen het en sodat jy kan sien watter personeellede in die foto's. So dan kan jy foto's neem met die personeel. Soms moet jy om hulle af te jaag. Waarskynlik 'n paar van hulle probeer om te hardloop weg van jou af. Jy neem foto's saam met hulle. Dit is aan die gang. Dit is nie te wyte wanneer die pset is. Die sperdatum sal aangekondig word in die spec. Dan saam met jou artikel, wat ookal artikel neem die meeste foto's met die meeste personeellede sal wen 'n pretty awesome prys. Dit is soort aansporing te kry jou pset4 klaar so gou as moontlik want dan kan jy vir sake jag af al die verskillende CS50 personeellede. Dit is nie verpligtend nie, maar, so wanneer jy kry die foto's, dan is jy klaar met pset4. En ek is klaar met Walk Through 4, so dankie vir almal se koms. Sterkte met Forensics. [Applous] [CS50.TV]