[Powered by Google Translate] [Walkthrough - Problem Set 4]
[Zamyla Chan - Harvarduniversitetet]
[Detta är CS50. - CS50.TV]
Okej. Hej, alla, och välkomna till Walkthrough 4.
>> Idag vår pset är kriminalteknik.
Forensics är ett riktigt roligt pset som innebär att hantera bitmappsfiler
att upptäcka som begått ett brott.
Sen ska vi ändra storlek några bitmappsfiler,
då vi också kommer att ta itu med ett riktigt roligt del som kallas Recover,
där vi i grund och botten överlämnade ett minneskort
där någon har oavsiktligt raderade alla sina filer,
och vi är ombedda att återställa dessa filer.
>> Men först, innan vi kommer in i pset, jag verkligen bara vill gratulera alla.
Vi är omkring vid mittpunkten av denna kurs.
Quiz 0 är bakom oss, och vi är på pset4, så i huvudsak är vi halvvägs.
Vi har kommit en lång väg om du ser tillbaka på dina psets, pset0 och pset1,
så gratulera dig själv om det,
och vi kommer att få in några riktigt roliga saker.
>> Så vår verktygslåda för pset, igen, i stället för att köra sudo yum-y uppdateringen
vi kan bara köra update50 om du är på version 17,3 eller högre av apparaten.
Så se till att köra update50 - det är mycket lättare, några mindre tecken -
att se till att du är på den senaste versionen av apparaten.
Speciellt är det viktigt att update50 när vi börjar använda CS50 Sök.
Så se till att du gör det.
>> För alla avsnitt för denna pset,
vi kommer att ha att göra med filen in-och utgångar, fil I / O.
Vi kommer att gå över en massa program som behandlar matriser
pekar på filer och sånt,
så vi vill se till att vi är riktigt bekant och bekväm
behandlar hur in-och utmatning till filer.
>> I fördelningen kod för denna pset är en fil som heter copy.c,
och det är vad vi kommer att hitta kommer att vara riktigt användbart för oss
eftersom vi kommer att hamna faktiskt kopierar copy.c filen
och bara ändra den något för att kunna uppnå de första 2 delarna av problemet uppsättningen.
>> Och så då som jag nämnde tidigare har vi att göra med bitmappar samt JPEG.
Så egentligen förstå strukturen för hur dessa filer är organiserade,
hur vi kan verkligen översätta 0 och 1 i structs
och saker som vi faktiskt kan förstå och tolka och redigera,
som kommer att vara mycket viktigt,
så gå in JPEG-och bitmappsfiler och förstå strukturen av dessa.
>> Pset4, som vanligt, börjar med en del av frågor.
De kommer att behandla fil I / O och få dig van vid det.
Då del 1 är deckare, där du ges en bitmappsfil
som ser ungefär som röda prickar överallt.
Och sedan i princip vad vi ska göra är att ta den här filen och bara redigera den något
i en version som vi kan läsa.
I huvudsak, när vi avslutar, vi får samma fil,
utom vi kommer att kunna se de dolda budskap döljs av alla dessa röda prickar.
Då Ändra storlek är ett program som, givet en fil
och sedan fick namnet på filen att det avger och sedan tilldelas ett nummer också,
faktiskt kommer att ändra storlek på den bitmappen av den heltalsvärde.
Då slutligen har vi Recover pset.
Vi får ett minneskort och sedan måste återvinna alla foton
som har tagits bort av misstag,
men som vi kommer att lära, inte bort och tas bort från filen,
Vi bara typ av förlorade där de var i filen, men vi kommer att återkräva.
>> Jättebra. Så gå in I / O-specifikt, det är en hel lista med funktioner som du kommer att använda.
Du har redan sett lite grunderna i fopen, fread och fwrite,
men vi kommer att titta närmare på en del fil-I / O-funktioner såsom fputc,
där du skriver bara ett tecken i taget,
till fseek där du slags flytta indikatorn filposition framåt och bakåt,
och sedan några andra. Men vi ska gå in i det lite senare under pset.
>> Så först, att bara få in I / O-innan vi går in i pset,
att öppna en fil, till exempel, är vad du måste göra faktiskt ställa en pekare till filen.
Så vi har en pekare fil *.
I det här fallet, jag kallar det en i pekare eftersom det kommer att bli min INFILE.
Och så ska jag använda funktionen fopen och sedan namnet på filen
och sedan läge där jag kommer att ha att göra med filen.
Så det finns "r" i det här fallet för att läsa, "w" för skrivning, och sedan "A" för att lägga till.
Till exempel när du arbetar med en INFILE
och allt du vill göra är att läsa bits och bytes lagrade där,
då du förmodligen kommer att vilja använda "r" som din läge.
När du vill verkligen skriva, typ av göra en ny fil,
vad vi ska göra är att vi ska öppna den nya filen
och använd "w"-läge för att skriva.
>> Så då när du faktiskt läser in filerna är strukturen enligt följande.
Först inkluderar pekaren till struct som ska innehålla de bytes som du läser.
Så det kommer att vara slutet platsen för byte som du läser.
Du kan sedan kommer att indikera storleken gillar i princip hur många byte
ditt program måste läsa in filen, storleken grunden en del är,
och då du kommer att ange hur många element som du vill läsa.
Och slutligen, måste du veta var du läser från,
så det kommer att bli din i pekaren.
Jag färgkodade dessa eftersom fread är också mycket lik fwrite,
förutom att du vill vara säker på att du använder rätt ordning,
se till att du faktiskt skriver till eller läser från höger fil.
>> Så då som förut, om vi har storleken av elementet samt antalet element,
då kan vi leka här lite.
Säg jag har en hund struct och så då vill jag läsa två hundar åt gången.
Vad jag kan göra är att säga storleken på en del kommer att vara storleken på en hund
och jag ska faktiskt läsa två av dem.
Alternativt är att säga vad jag kunde göra jag bara tänker läsa en del
och att en del kommer att vara storleken på två hundar.
Så det är analog hur du kan slags leka med storlek och antal
beroende på vad som är mer intuitiv för dig.
>> Okej. Så nu får vi skriva filer.
När du vill skriva en fil är det första argumentet faktiskt var du läser från.
Så det är i princip de uppgifter som du ska skriva in i filen,
vilket är den ute pekaren slutet.
Så när du arbetar med pset, se till att du inte blir förvirrad.
Kanske har definitionerna sida vid sida.
Du kan dra definitionerna i handboken genom att skriva man och sedan fwrite, till exempel,
i terminalen, eller så kan du hänvisa till denna bild
och se till att du använder rätt.
Så återigen, för fwrite, när du har en fil som du vill skriva in,
det kommer att bli det sista argumentet och det kommer att bli en pekare till filen.
Så då det är hur vi handskas med att skriva kanske flera byte i taget,
men säger att du vill bara skriva på bara ett enda tecken.
Som vi kommer att se senare i detta exempel, i bitmappar vi får använda den.
Det är då vi kan använda fputc, i huvudsak bara sätta ett tecken i taget, chr,
i filen pekaren, och det är vår ute pekare där.
Så då när vi söker eller skriva i en fil,
filen att hålla reda på var vi är.
Så det är ett slags markör, filen lägesindikator.
Och så när vi skriver eller läser igen i en fil,
filen minns faktiskt där det är,
och så fortsätter det där markören är.
Detta kan vara bra när du vill, säg, läsa i en viss mängd för att göra något
och sedan läsa i följande belopp,
men ibland vi kanske vill gå tillbaka eller faktiskt börja från en viss referensvärde.
Så då fseek funktionen, vad den gör är låter oss flytta markören i en viss fil
ett visst antal byte.
Och vad vi måste göra är ange var referensvärdet är.
Så antingen det rör sig framåt eller bakåt från där markören för tillfället är,
eller så kan vi ange att det bara skulle röra sig från början av filen
eller från slutet av filen.
Och så kan du skicka in negativa eller positiva värden till belopp,
och som kommer slags flytta markören antingen framåt eller bakåt.
>> Innan vi kommer till de andra psets, några frågor om fil-I / O?
Okej. När vi kommer in fler exempel, gärna stoppa mig för frågor.
>> Så i DECKARE, du gav en bitmappsfil som liknar detta röda på bilden,
och det ser ut så här - ett gäng röda prickar - och du vet inte riktigt vad som är skrivet.
Om du kisa, kanske du kan se en liten blåaktig färg inne i mitten.
Huvudsak, det är där texten lagras.
Det var ett mord som skedde, och vi måste ta reda på vem som gjorde det.
För att kunna göra det måste vi sorts omvandla bilden till ett läsbart format.
Om ni någonsin stött på detta, ibland skulle det finnas lite kit
där du skulle ha ett förstoringsglas med en röd film. Någon? Ja.
Så du skulle överlämnas något sådant, skulle du ha ett förstoringsglas
med den röda filmen över den, skulle du placera den över bilden,
och du skulle kunna se meddelandet gömd däri.
Vi har inte ett förstoringsglas med röd film, så istället ska vi typ av skapa vår egen
i detta pset.
Och så att användaren ska mata DECKARE, sedan ledtråd,. Bmp,
så det är INFILE, det är den röda pricken meddelandet,
och då de säger verdict.bmp kommer att vara vår utfil.
Så det kommer att skapa en ny bitmappsbild liknar ledtråden en
förutom i ett läsbart format där vi kan se de dolda budskap.
>> Eftersom vi kommer att ha att göra med att redigera och manipulera bitmappar av något slag,
vi ska typ av dyk in i strukturen av dessa bitmappsfiler.
Vi gick över dessa lite i föreläsning, men låt oss titta på dem lite mer.
Bitmappar är i huvudsak bara ett arrangemang av byte
där vi har angett vilka byte menar vad.
Så här är ungefär som en karta över bitmappsbilden
säger att det börjar med några header-filer, börjar med lite information där.
Du ser att ungefär byte nummer 14 storleken anges av bitmappsbilden,
och det fortsätter på.
Men vad vi verkligen intresserade av här börjar runt byte nummer 54.
Vi har dessa RGB tripplar.
Vad som kommer att göra är att innehålla de faktiska pixlar, färgvärdena.
Allt ovan att i huvudet är lite information
motsvarar storleken på bilden, bredden på bilden, och höjden.
När vi går in stoppning senare, vi får se varför storleken på bilden
kan vara annorlunda än bredden eller höjden.
Så då att representera dem - dessa bitmappsbilder är sekvenser av byte -
vad vi kan göra är att säga okej, jag ska komma ihåg att på index 14,
det är där storlek är till exempel utan vad vi ska göra för att underlätta detta
är kapsla den i en struktur.
Och så har vi två structs gjort för oss, en BITMAPFILEHEADER
och en BITMAPINFOHEADER,
och så när vi läser in i filen som standard det kommer att gå i ordning,
och så för det kommer också att fylla i till variabler såsom biWidth och biSize.
Och slutligen, är varje pixel representeras av tre byte.
Den första är mängden blått i pixeln, är den andra mängden grönt,
och slutligen, mängden rött, där 0 är väsentligen ingen blå eller ingen grön eller inget rött
och sedan ff är det maximala värdet.
Dessa är hexadecimala värden.
Så då om vi har FF0000, då motsvarar den maximala mängden blått
och då ingen grön och ingen röd, så då skulle ge oss en blå pixel.
Sen om vi har ff oss alla över hela linjen, då det innebär att vi har en vit pixel.
Detta är typ av motsatsen till normalt när vi säger RGB. Det faktiskt kommer BGR.
>> Så om vi verkligen undersöka ett exempel på en bitmappsbild - låt mig dra en här uppe.
Det är lite små.
Jag zooma in, och vi kan se det är taggiga ut. Det ser ut som block av färg.
Du har vita block och sedan röda block.
Om du spelar i Microsoft Paint, till exempel, kan du göra något liknande
genom i princip bara måla vissa rutor i en viss ordning.
Så vad detta innebär i bitmappen är som följer.
Här har vi första vita pixlar, att alla 6 är F: s, och sedan har vi röda pixlar,
indikeras med 0000FF.
Och så den sekvens byte som vi har visar hur bitmappsbilden kommer att se.
Så vad jag har gjort här är just skrivit ut alla dessa byte och sedan färgade i rött
så att du kan typen av se, om du kisar lite, hur den typen av indikerar en smiley.
>> Det sätt som bitmappsbilder arbete är jag föreställer det i grunden som ett rutnät.
Och så som standard har varje rad i rutnätet är en multipel av 4 byte.
Om vi ​​tittar på en bitmappsbild, du fyller i alla värde.
Till exempel kan du ha en röd här, en grön här, en blå här,
men du måste se till att bilden fylls i med en multipel av fyra byte.
Så om jag vill att min bild är tre kvarter bred, då skulle jag behöva sätta ett tomt värde
i den sista för att göra det en multipel av fyra.
Så då skulle jag lägga i något som vi kallar stoppning.
Jag ska bara visa att det med ett x.
Nu säger vi vill ha en bild som är 7 pixlar lång, till exempel.
Vi har 1, 2, 3, 4, 5, 6, 7,
och allt som är fylld med färg.
Det sätt som bitmappsbilder fungera är att vi behöver en 8: e.
Just nu har vi 1, 2, 3, 4, 5, 6, 7.
Vi behöver 8 platser för bitmappsbilden för att läsa korrekt.
Så vad vi måste göra är att lägga in bara lite stoppning
att se till att alla bredder är enhetliga
och att alla bredder är en multipel av 4.
Och så jag visade tidigare vaddering som X eller en snirklig linje,
men i själva bitmappsbilder stoppningen indikeras av en hexadecimal 0.
Så det skulle vara ett enstaka tecken, 0.
Vad kan vara bra att ha är den XXD kommandot.
Vad den gör är faktiskt visar du, liksom liknar vad jag gjorde innan med smiley
När jag skrivs faktiskt ut vad varje färg skulle vara för pixeln
och sedan färgkodade det, när du kör XXD med följande kommandon,
så kommer det faktiskt skriva ut vad färgerna är för dessa pixlar.
Vad du behöver göra är över här jag ange som-s 54
säger att jag ska börja på den 54: e byte
eftersom innan att komma ihåg om vi ser tillbaka till kartan i bitmappar,
det är allt rubrikinformation och sånt.
Men vad vi verkligen bryr oss om är den faktiska pixlar som indikerar färgen.
Så genom att lägga i den flagga,-s 54, då vi kan se färgvärdena.
Och oroa dig inte om de komplicerade flaggor och sånt.
I problembild spec, har du anvisningar om hur du XXD använda för att visa pixlar.
Så om du ser här, det slags ser ut som en grön ruta, denna lilla sak.
Jag har färgkodade för 00FF00 som i princip säga nej blå, mycket grönt och ingen röd.
Så som motsvarar grönt.
Som du ser här ser vi en grön rektangel.
Denna gröna rektangeln är bara 3 pixlar bred, så vad vi måste göra
att se till att bilden är en multipel av 4 bred är att lägga i extra stoppning.
Och så då det är hur du ser dessa 0s här.
Detta kommer faktiskt vara resultatet av din Omformatera pset,
huvudsak tar lilla bitmapp och sedan utvidga den med 4.
Och så vad vi ser är att faktiskt denna bild är 12 pixlar bred, men 12 är en multipel av 4,
och så att vi faktiskt inte se någon 0s slutet eftersom vi inte behöver lägga något
eftersom det är helt vadderad. Det har inte någon mer utrymme.
>> Okej. Har du frågor om stoppning?
Okej. Cool.
>> Som jag nämnde tidigare, de bitmappar är bara en sekvens av bytes.
Och så vad vi har är i stället för att behöva hålla reda på exakt vilka antalet byte
motsvarar en specifik del, vi faktiskt har skapat en struktur för att representera det.
Så vad vi har är en RGBTRIPLE struct.
När du har en instans av en RGB trippel,
eftersom detta är en typ definierar struct, så du kan komma åt rgbtBlue variabel,
Likaså gröna och röda variabler, som indikerar hur mycket blått, grönt och rött,
respektive har du.
>> Så om vi har den blå variabeln inställd på 0, den gröna satt till ff,
vilket är det högsta värde som du kan ha, och sedan den röda variabeln satt till 0,
vad färg skulle detta RGB trippel representerar? >> [Elev] Green.
Grön. Exakt.
Det kommer att vara bra att veta att när du har en instans av en RGB trippel,
du kan faktiskt komma åt mängden färg - blå, grön och röd - för sig.
>> Nu när vi har pratat om strukturen av det, låt oss ta en titt på BMP-fil.
Dessa är structs gjorda för dig.
Här har vi en BITMAPFILEHEADER struct.
Av intresse är storleken.
Senare har vi info huvudet, som har några fler saker som är intressant för oss,
nämligen storleken, bredden och höjden.
När vi ska gå in senare när du läser in i filen,
det står automatiskt eftersom vi har ställt in för att vara detsamma.
Så biSize innehåller rätt byte som motsvarar den verkliga storleken på bilden.
Och sedan här, slutligen, som vi har pratat om, vi har RGBTRIPLE typedef struct.
Vi har en rgbtBlue, grönt och rött i samband med det.
>> Jättebra. Okej.
Nu när vi förstår bitmappar lite, förstår att vi har ett filhuvud
och ett info huvud i samband med det och sedan efter det har vi intressanta saker
av färger och de färger representeras av RGBTRIPLE structs,
och de har i sin tur har tre värden som är associerade till blått, grönt och rött.
>> Så nu kan vi slags tänker på Återställa lite.
Ursäkta. Tänk på deckare.
När vi har vår ledtråd fil, vad vi vill göra är att läsa in till den pixel för pixel
och sedan på något sätt ändra dessa pixlar så att vi kan mata den till ett läsbart format.
Och så för att mata den, vi ska skriva pixel för pixel i verdict.bmp filen.
Det är lite av en hel del att göra. Vi inser att.
Så vad vi har gjort är att vi faktiskt har gett dig copy.c.
Vad copy.c gör är bara gör en exakt kopia av en viss bitmappsfil och matar sedan ut det.
Så detta öppnar redan filen för dig, läser in pixel för pixel,
och sedan skriver det i en utdatafil.
>> Låt oss ta en titt på det.
Detta är att se korrekt användning,
få filnamnen här.
Vad detta innebär är det sätter indatafilen är vad vi har gått in i INFILE här,
vilket är vår andra kommandoradsargument.
Kontrollerar att se till att vi kan öppna filen.
Kontrollerar att vi kan göra en ny utfil här.
Sedan vad detta innebär här, det bara grunden börjar läsa in till bitmappsfilen från början.
Början, som vi vet, innehåller BITMAPFILEHEADER,
och så dessa sekvenser av bitar kommer direkt fylla i BITMAPFILEHEADER.
Så vad vi har här säger att BITMAPFILEHEADER bf -
Det är vår nya variabel av typen BITMAPFILEHEADER -
vi kommer att sätta in bf vad vi läser från i pekare, vilket vår INFILE.
Hur mycket läser vi?
Vi läser i hur många byte behöver vi innehålla hela BITMAPFILEHEADER.
Likaså är det vad vi gör för info sidhuvudet.
Så vi fortsätter längs vår fil i INFILE,
och vi läser dessa bitar och bytes, och vi ansluter dem direkt i
i dessa fall av de variabler som vi gör.
Här är vi bara se till att bitmappen är en bitmapp.
>> Nu har vi en utfil, eller hur?
Så som det ser när vi skapar det, är det i huvudsak tom.
Så vi måste i princip skapa ett nytt bitmapp från grunden.
Vad vi gör är att vi måste se till att vi kopierar i filhuvudet
och info huvudet precis som INFILE har.
Vad vi gör är att vi skriver - och kom ihåg att bf är den variabel
av typen BITMAPFILEHEADER, så vad vi gör är att vi bara använder det innehåll
skriva in i utfil.
Här minns vi talade om stoppning,
hur det är viktigt att se till att den mängd pixlar som vi har är en multipel av 4.
Detta är en ganska bra formel för att beräkna hur mycket stoppning du har
med tanke på bredden på din fil.
Jag vill att ni ska komma ihåg att i copy.c vi har en formel för att beräkna stoppning.
Okej? Så alla ihåg. Jättebra.
Så vad copy.c gör härnäst är det itererar över alla Scanlines.
Den går genom raderna först och sedan lagrar varje trippel att den läser
och sedan skriver in den utfil.
Så så här vi läser bara en RGB trippel i taget
och sedan sätta samma trippel i utfil.
Den svåra delen är att stoppningen inte är en RGB-trippel,
och så att vi inte bara kan läsa det stoppning mängd RGB tripplar.
Vad vi måste göra är faktiskt bara flytta vår indikator fil flyttar du vår markören,
till typ av hoppa över all stoppning så att vi är på nästa rad.
Och vad detta innebär är kopieringsskyddad visar hur du kanske vill lägga till stoppning.
Så vi har beräknat hur mycket stoppning vi behöver,
så det betyder att vi behöver stoppning antal 0s.
Vad detta innebär är en for-slinga som sätter stoppning antal 0s i vår utfil.
Och slutligen, stänger du båda filerna. Du stänger INFILE samt utfil.
>> Så det är hur copy.c verk,
och det kommer att vara ganska bra.
Istället för att bara faktiskt direkt kopiera och klistra
eller bara titta på den och skriva in vad du vill,
du kanske bara vill köra detta kommando i terminalen,
cp copy.c whodunit.c, vilket kommer att skapa en ny fil, whodunit.c,
som innehåller exakt samma innehåll som kopia gör.
Så då vad vi kan göra är att använda det som ett ramverk på att bygga och redigera
för vår DECKARE fil.
>> Dessa är vår att-DOS att göra för DECKARE, men vad copy.c gör
faktiskt tar hand om de flesta av dem för oss.
Så allt vi behöver göra härnäst är att ändra pixlarna som behövs
att faktiskt göra filen läsbar.
Kom ihåg att för en given pixel trippel, så för en given variabel av typen RGBTRIPLE,
kan du komma åt de blå, gröna och röda värden.
Det kommer att komma till hands för om du kan komma åt dem,
det betyder att du också kan kontrollera dem,
och det betyder att du även kan ändra dem.
>> Så när vi gick tillbaka till vårt röda förstoringsglas exempel
princip, var att fungera som en slags filter för oss.
Så vad vi vill göra är att vi vill filtrera alla tripplar som kommer in
Det finns flera olika sätt att göra detta.
I princip kan du ha vilken typ av filter du vill.
Kanske du vill ändra alla röda pixlar
eller kanske du vill ändra en annan färg pixel till en annan färg.
Det är upp till dig.
Kom ihåg att du kan kontrollera vilken färg pixeln är
och sedan kan du också ändra det som du går igenom.
>> Okej. Så det är deckare.
När du kör DECKARE, vet du vem den skyldige för brottet var.
>> Nu ska vi gå till Ändra storlek.
Vi kommer att fortfarande ha att göra med bitmappar.
Vad vi ska göra är att vi kommer att ha en ingång bitmapp
och då ska vi gå på ett nummer och sedan få en utfil bitmapp
där det är i princip vår INFILE skalas av n.
Säg min fil var bara en pixel stor.
Sedan om min n var 3, skalning med 3, då skulle jag upprepa att pixel n antal gånger,
så 3 gånger och då också skala ner 3 gånger också.
Så du ser att jag skalning det vertikalt och horisontellt.
>> Och så här är ett exempel.
Om du har n = 2, ser du att den första blå pixel det upprepas två gånger
horisontellt samt två gånger vertikalt.
Och då fortsätter vidare, och så har du en direkt skalning av den ursprungliga bilden med två.
>> Så då om vi skulle detalj pseudokod för detta vill vi öppna filen.
Och sedan veta att om vi går tillbaka hit,
Vi ser att bredden för utfil kommer att vara annorlunda än bredden för infil.
Vad betyder det?
Det innebär att vår rubrikinformation kommer att förändras.
Och så vad vi kommer att vilja göra är att uppdatera huvudet info,
att veta att när vi läser i filerna om du arbetar på copy.c ramen,
Vi har redan en variabel som visar vilken storlek är och sånt.
Så när du har det, vad du skulle vilja göra är att byta dessa särskilda variabler.
Kom ihåg att om du har en struct, hur du komma åt variablerna i det.
Du använder punktoperatorn, eller hur?
Så då använda den, du vet att du måste ändra rubriken info.
Så här är bara en lista av de faktiska element som kommer att förändras i din fil.
Filstorleken kommer att förändras, bilden, liksom bredden och höjden.
Så då gå tillbaka till kartan på bitmappar,
titta på om det är filhuvudet eller info rubrik som innehåller denna information
och sedan ändra om det behövs.
Återigen säger cp copy.c resize.c.
Det innebär att resize.c nu innehåller allt som finns inuti kopia
eftersom kopiering ger oss ett sätt att läsa in varje scanline pixel för pixel.
Utom nu, i stället för att bara ändra värdena som vi gjorde i DECKARE,
vad vi vill göra är att vi vill skriva i flera pixlar
så länge som vår n är större än 1.
>> Vad vi vill göra är att vi vill sträcka ut den horisontellt med n,
samt sträcka den vertikalt med n..
Hur kan vi göra detta?
Säg din n är 2 och du har denna givna INFILE.
Markören kommer att börja på den första,
och vad du vill göra om n är 2, vill du skriva ut i 2 av dem.
Så du skriva ut i 2 av dem.
Sedan markören kommer att flytta till nästa pixel, vilket är den röda en,
och det kommer att skriva ut 2 av de röda, lägga den på vad det gjort tidigare.
Då markören flyttas till nästa pixel och dra i 2 av dem.
Om man ser tillbaka till den copy.c ramen, vad detta innebär här
är den skapar en ny instans av en RGB trippel, en ny variabel kallad triple.
Och här när den läser in det, läser det från INFILE 1 RGBTRIPLE
och lagrar det inne i den trippel variabel.
Så då har du faktiskt en variabel som representerar just den pixeln.
Sedan när du skriver, vad du skulle vilja göra är innesluta den fwrite uttalande i en for-slinga
som skriver in den på din utfil så många gånger som behövs.
Det är enkelt nog.
Bara princip upprepa skrivprocessen n antal gånger för att skala den horisontellt.
>> Men då måste vi komma ihåg att vår stoppning kommer att förändras.
Tidigare säga att vi hade något med längden 3.
Då skulle vi bara lägga in hur mycket stoppning? Bara en att göra det en multipel av 4.
Men säger att vi skalar denna bild med n = 2.
Så hur många blå bildpunkter skulle vi ha i slutet? Vi skulle ha 6.
1, 2, 3, 4, 5, 6. Okej.
6 är inte en multipel av 4. Vad är närmaste multipel av 4? Det kommer att vara 8.
Så vi faktiskt kommer att ha 2 tecken stoppning där.
>> Minns någon om vi har en formel för att beräkna stoppning
och där det kan vara?
[Ohörbart elev svar] >> Ja, copy.c. Rätt.
Det finns en formel i copy.c att beräkna hur mycket stoppning du har
ges en särskild bredd bitmappsbilden.
Så då det kommer att vara användbart när du behöver lägga till i en viss stoppning
att faktiskt räkna ut hur mycket stoppning du behöver lägga till.
Men en anmärkning, är dock att du vill vara säker på att du använder rätt storlek.
Bara vara försiktig eftersom du i princip kommer att ha att göra med två bitmappsbilder.
Du vill vara säker på att du använder rätt.
När du beräkna stoppning för utfil, du vill använda bredden på utfil
och inte bredden av den föregående.
>> Jättebra. Denna typ av tar hand om stretching en hel bitmappsbild horisontellt.
Men vad vi vill göra är att sträcka faktiskt vertikalt liksom.
Detta kommer att bli lite svårare eftersom när vi har kopierat en rad
och skriva den raden är vår markören kommer att vara i slutet.
Så om vi läser igen, då det bara kommer att läsa in i nästa rad.
Så vad vi vill göra är typ av att hitta något sätt att kopiera dessa rader igen
eller bara typ att ta den raden och sedan skriva det igen.
När jag slags hänvisade till, det finns flera olika sätt att göra detta.
Vad du kan göra är som du går igenom och läsa igenom den särskilda avsökningsraden
och ändra den vid behov, då slags lagra alla dessa pixlar i en array.
Senare på du vet att du behöver för att skriva ut den arrayen igen,
och så kan du bara använda den matris att göra det.
Ett annat sätt att göra det är att du kan kopiera ner en rad,
förstår att du behöver kopiera det igen, så faktiskt flytta markören,
och det kommer att bli med metoden fseek.
Du kan flytta markören hela vägen tillbaka och sedan upprepa kopieringen igen.
>> Så om vi skalning nummer är n, hur många gånger skulle vi gå tillbaka
och skriva en rad? >> [Eleven] n - 1. >> Ja, perfekt. n - 1.
Vi har gjort det en gång redan, så vi kommer att vilja upprepa gå tillbaka processen
n - 1 antal gånger.
Okej. Där har ni er storleksändring funktion.
>> Nu kan vi få till en riktigt rolig del, min favorit pset, vilket är Recover.
Istället för bitmappar, denna gång vi har att göra med JPEG.
Vi är faktiskt inte gett en fil bara av JPEG,
vi ges grunden en RAW-format minneskort.
Och så detta innehåller lite info och skräp värden i början,
och då det börjar och den har en massa JPEG-filer.
Men vi överlämnade en kort där vi har tagit bort bilderna;
huvudsak har vi glömt var bilderna finns inom kort.
Så då vår uppgift i Recover är att gå igenom detta kort format
och hitta dessa bilder igen.
>> Lyckligtvis är strukturen av JPEG-filer och kortet filen lite hjälp.
Det definitivt kunde ha varit lite svårare om det inte vore i detta format.
Varje JPEG-fil börjar faktiskt med två möjliga sekvenser, som anges ovan.
I grund och botten, när du har en ny JPEG-fil,
det börjar med antingen sekvensen ffd8 ffe0 eller den andra, ffd8 ffe1.
En annan användbar sak att veta är att JPEG-bilder lagras intill varandra.
Så när en JPEG-fil slutar, de övriga en starter.
Så det finns inte någon form av in-mellan värden där.
När du träffar i början av en JPEG, om du redan har läst en JPEG,
du vet att du har drabbats slutet av föregående och början av nästa.
>> Till typ av visualisera detta gjorde jag en schematisk.
En annan sak om JPEG är att vi kan läsa dem i sekvenser av 512 byte i taget,
liknande med början av kortet.
Vi behöver inte vara att kontrollera varenda byte eftersom det skulle suga.
Så istället vad vi kan göra är faktiskt bara läsa i 512 byte åt gången
och sedan, i stället för att checka in mellan dem i de små små skivor,
Vi kan bara kolla i början av 512 byte.
Huvudsak på bilden, vad du ser är i början av kortet,
du har värden som inte riktigt relevant för de faktiska JPEG själva.
Men vad jag har är en stjärna för att ange en av de två start sekvenser för en JPEG.
Så när du ser en stjärna, du vet att du har en JPEG-fil.
Och därefter var JPEG-fil kommer att vara någon multipel av 512 byte
men inte nödvändigtvis samma multipel.
Det sätt som du vet att du har drabbats annan JPEG är om du träffar en annan stjärna,
annan startsekvens byte.
Vad ni har här är att du har den röda JPEG-fil fortsätter tills du träffar en stjärna,
vilket indikeras av en ny färg.
Du fortsätter sedan du träffar en annan stjärna, slår dig en JPEG,
du fortsätter ända till slutet.
Du är på sista bilden här, den rosa.
Du går till slutet tills du träffar slutet av filen karaktär.
Detta kommer att bli riktigt bra.
>> Några viktiga takeaways här:
Kortet Filen börjar inte med en JPEG,
men när en JPEG startar, är alla JPEG lagrade sida vid sida till varandra.
>> Vissa pseudokod för Recover.
Först kommer vi att öppna våra kort fil,
och det kommer att använda vår fil I / O funktioner.
Vi kommer att upprepa följande process tills vi har nått slutet av filen.
Vi kommer att läsa 512 byte i taget.
Och vad jag sa här är att vi ska förvara den i en buffert,
så i princip hålla fast vid de 512 byte tills vi vet exakt vad de ska göra med dem.
Vad vi vill göra är att vi vill kontrollera om vi har träffat en stjärna eller inte.
Om vi ​​har träffat en stjärna, om vi har drabbats en av utgångspunkterna sekvenser,
då vet vi att vi har träffat en ny JPEG-fil.
Vad vi vill göra är att vi kommer att vilja skapa en ny fil i vår pset4 katalog
att fortsätta att göra den filen.
Men också om vi har redan gjort en JPEG innan,
då vi vill avsluta den filen och tryck på pset4 mappen
där vi kommer att ha den filen lagras för om vi inte anger att vi har hamnat att JPEG-fil,
då vi i grund och botten har en obestämd mängd. De JPEG tar aldrig slut.
Så vi vill se till att när vi läser in en JPEG-fil och skriva det,
Vi vill uttryckligen stänga den för att öppna nästa.
Vi kommer att vilja kontrollera flera saker.
Vi vill kontrollera om vi är i början av en ny JPEG med vår buffert
och även om vi redan har hittat en JPEG innan
eftersom det kommer att förändra din process något.
Så då efter att du går igenom hela vägen och du träffar i slutet av filen,
vad du vill göra är att du vill stänga alla filer som är öppna.
Som förmodligen kommer att bli den sista JPEG-fil som du har,
liksom det kort-fil som du har att göra med.
>> Det sista hindret som vi måste ta itu är hur man faktiskt gör en JPEG-fil
och hur man faktiskt driva det till mappen.
Den pset kräver att varje JPEG som du hittar vara i följande format,
där du har numret. JPG.
Numret, även om det är 0, vi kallar det 000.jpg.
När du hittar en JPEG i ditt program,
du kommer att vilja namnge den i den ordning som det är finns.
Vad betyder det här?
Vi behöver sorts hålla reda på hur många vi har hittat
och vad antalet varje JPEG bör vara.
Här ska vi dra nytta av den sprintf funktionen.
I likhet med printf, som bara typ av utskrifter ett värde ut i terminalen,
sprintf skrivs filen ut till mappen.
Och så vad det skulle göra om jag hade sprintf, titel och sedan strängen där,
Det skulle skriva ut 2.jpg.
Förutsatt att jag har stängt mina filer korrekt,
som skulle innehålla filen som jag hade skrivit ut.
Men en sak är att koden som jag har här
inte riktigt uppfyller vad pset kräver.
Den pset kräver att den andra JPEG-filen ska namnges 002 istället för bara 2.
Så när du skriver ut namnet, så kanske du kanske vill ändra platshållaren något.
>> Minns någon hur vi tillåter extra mellanslag när vi skriva ut något?
Ja. >> [Elev] Du sätter en 3 mellan procenttecken och 2. >> Ja, perfekt.
Du kommer att sätta en 3 i det här fallet eftersom vi vill plats för 3.
% 3d skulle förmodligen ge dig 002.jpg istället för 2.
Det första argumentet i sprintf funktionen är faktiskt en char array,
som vi visste tidigare som strängar.
De vilja, typ av mer som en tillfällig lagring, bara lagra den resulterande strängen.
Du kommer inte riktigt att göra med detta, men du måste inkludera den.
>> Att veta att varje filnamn har numret, som tar upp tre tecken,
och då. jpg, hur länge denna array vara?
Kasta ut ett nummer. Hur många tecken i rubriken, i namnet?
Så det finns 3 hashtags, period, jpg. >> [Elev] 7. >> 7. Inte riktigt.
Vi kommer att ha 8 eftersom vi vill tillåta null avslutare också.
>> Slutligen, för att bara dra ut den process som du ska göra för Recover,
du har någon början information.
Du fortsätter tills du hittar början på en JPEG-fil,
och som kan vara antingen en av två start sekvenser.
Du håller på att läsa. Varje snedstreck här representerar 512 bytes.
Du håller på att läsa, fortsätt läsa tills du stöter annan startsekvens.
När du har det, du avslutar den aktuella JPEG - i det här fallet är det den röda,
så du vill avsluta den.
Du vill sprintf namnet på det i din pset4 mapp,
då du vill öppna ett nytt JPEG och sedan hålla på att läsa
tills du stöter på nästa.
Fortsätta läsa, fortsätta läsa,
och slutligen, så småningom kommer du att nå slutet av filen,
och så du vill stänga den sista JPEG som du arbetade med,
sprintf det i din pset4 mapp och sedan titta på alla de bilder som du har fått.
Dessa bilder är faktiskt bilder på CS50 anställda,
och så det är där bonusen roliga delen av pset kommer i
är att du tävlar i dina sektioner för att hitta TF på bilderna
och ta bilder med dem för att bevisa att du har gjort pset
och så att du kan se vilka anställda är på bilderna.
Så då du tar bilder med personalen. Ibland måste du jaga dem.
Förmodligen några av dem kommer att försöka springa ifrån dig.
Du tar bilder med dem.
Detta pågår. Det är inte på grund när pset beror.
Tidsfristen kommer att meddelas i spec.
Då tillsammans med din sektion, tar beroende avsnitt de bilderna
med de mest anställda kommer att vinna en ganska häftigt pris.
Det är typ av incitament för att få din pset4 slutade så snabbt som möjligt
för då kan du komma till saken
jaga alla de olika CS50 anställda.
Det är inte obligatoriskt, men så när du får bilderna,
då du är klar med pset4.
>> Och jag är klar med Walkthrough 4, så tack alla för att ni kom.
Lycka till med kriminalteknik. [Applåder]
[CS50.TV]