[Powered by Google Translate] [Walkthrough - Set Problema 4] [Zamyla Chan - Universitatea Harvard] [Acest lucru este CS50. - CS50.TV] Bine. Bună ziua, tuturor, si bun venit la Walkthrough 4. Astazi PSET nostru este criminalistica. Criminalistica este un foarte distractiv, care PSET presupune lucrul cu fișiere bitmap pentru a descoperi care a comis o infracțiune. Apoi, vom redimensiona unele fișiere bitmap, apoi vom merge, de asemenea, să se ocupe de o parte foarte distractiv numit Recuperare, în care suntem înmânat de fapt un card de memorie în care cineva a șters accidental toate fișierele lor, și ni se cere să recupereze aceste fișiere. Dar, în primul rând, înainte de a ajunge în PSET, eu chiar vreau doar să-l felicit pe toți. Suntem pe cale de la punctul de mijloc al acestui curs. Chestionar 0 este în spatele nostru, și noi suntem la pset4, deci, în esență, suntem la jumatatea drumului. Am parcurs un drum lung, dacă te uiți înapoi la psets dvs., pset0 și pset1, deci te felicit cu privire la faptul că, și vom intra în niște chestii foarte distractiv. Deci, set de instrumente nostru pentru acest PSET, din nou, în loc de a rula sudo yum-y update, suntem capabili de a rula doar update50 daca esti la versiunea 17.3 și mai sus a aparatului. Deci, asigurați-vă că pentru a rula update50 - e mai ușor o mulțime, câteva personaje mai puțin - pentru a vă asigura că sunteți la cea mai recentă versiune a aparatului. Mai ales că e important să update50 atunci când vom începe să utilizați CS50 Data Check. Deci, asigurați-vă că faceți asta. Pentru toate secțiunile pentru acest PSET, vom fi de-a face cu intrări și ieșiri de fișiere, file I / O. Vom fi merge peste o mulțime de programe care se ocupă cu matrice subliniind fișiere și lucruri de genul asta, așa că doriți să vă asigurați că suntem cu adevărat familiară și confortabilă de-a face cu modul de a de intrare și de ieșire în fișiere. În codul de distribuție pentru acest PSET este un fișier numit copy.c, și asta e ceea ce am de gând să găsească va fi foarte util pentru noi pentru că vom ajunge de fapt, copierea fișierul copy.c și doar schimbând ușor să fie în măsură să realizeze primele 2 părți ale set de probleme. Și așa cum am menționat atunci înainte, avem de-a face cu fișiere bitmap, precum și JPEG. Deci, într-adevăr înțelegerea structurii de modul în care aceste fișiere sunt organizate, cum putem traduce într-adevăr 0s și 1s în structs și lucrurile pe care le pot înțelege și interpreta de fapt și edita, care va fi foarte important, astfel a intra în JPEG și fișiere bitmap și înțelegerea structurii acestora. Pset4, ca de obicei, începe cu o secțiune de întrebări. Cei se va ocupa de dosar I / O și te obișnuiți cu asta. Apoi, partea 1 este roman sau film polițist, în care ai de dat un fișier de tip bitmap care arata un fel de pete roșii peste tot. Și apoi, practic ceea ce am de gând să faceți este să luați acest fisier si doar o editați ușor într-o versiune pe care le putem citi. În esență, după ce vom termina, vom avea același fișier, cu excepția vom putea vedea mesajul ascuns ascuns de toate acele puncte roșii. Atunci Resize este un program care, având în vedere un fișier și având în vedere apoi numele fișierului pe care să emită și dat apoi un număr la fel de bine, va redimensiona de fapt, că bitmap de această valoare întreagă. Apoi în sfârșit, avem PSET recupera. Ni se dă o cartelă de memorie și apoi trebuie să recupereze toate fotografiile care au fost șterse accidental, dar, după cum vom afla, nu, de fapt, șterse și eliminate din dosar; am doar un fel de pierdere în cazul în care acestea au fost în dosar, dar vom recupera. Mare. Deci, merge într-un fișier I / O, în mod special, acestea sunt o listă întreagă de funcții pe care le veți folosi. Ati vazut deja un pic elementele de bază ale fopen, fread, fwrite și, dar ne vom uita mai departe, în unele file I / O funcții, cum ar fi fputc, în care se scrie doar un caracter la un moment dat, la fseek, în cazul în care vă mutați fel de indicatorul de poziție fișierul înainte și înapoi, și apoi altele. Dar noi vom merge în faptul că un pic mai târziu, în timpul PSET. Deci, mai întâi, doar pentru a obține într-un fișier I / O, înainte de a merge în PSET, pentru a deschide un fișier, de exemplu, ceea ce trebuie să faceți este să setați, de fapt un pointer la acel fișier. Deci avem un pointer * FILE. În acest caz, am numind-o un indicator pentru că, în va fi infile mea. Și așa am de gând să utilizeze funcția fopen și apoi numele fișierului și apoi modul în care am de gând să se ocupe cu fișierul. Deci nu e "r", în acest caz, pentru a citi, "w", pentru scris, și apoi "o" pentru extensia. De exemplu, atunci când ai de a face cu un infile și tot ce doriți să faceți este să citiți biți și bytes stocate acolo, atunci esti, probabil, de gând să doriți să utilizați "r" ca modul tău. Când doriți să scrie de fapt, un fel de a face un fișier nou, atunci ceea ce am de gând să faceți este să mergem pentru a deschide noul fișier și de a folosi "w" modul de scriere. Deci, atunci când sunteți de fapt, citind în fișiere, structura este după cum urmează. În primul rând să includeți indicatorul pentru a struct care va conține octeți pe care îl citesc. Așa că va fi locația sfârșitul octeți pe care îl citesc. Te apoi merge pentru a indica dimensiunea, ca principiu, cât de multe bytes programul dumneavoastră trebuie să citesc în la dosar, dimensiunea practic un element este, si apoi ai de gând să specificați cât de multe elemente pe care doriți să îl citiți. Și apoi în cele din urmă, trebuie să știi unde te citind din, astfel încât va fi indicatorul în. Am culorilor, acestea deoarece fread este de asemenea foarte asemanatoare cu fwrite, , cu excepția doriți să vă asigurați că utilizați ordinea corectă, asigurați-vă că sunteți de fapt, scriere sau citire din fișierul dreapta. Deci la fel ca înainte, dacă avem dimensiunea elementului, precum și numărul de elemente, atunci putem juca în jurul valorii de aici, un pic. Spune că am un câine și struct da, atunci vreau să citesc doi caini, la un moment dat. Ce am putea face este marimea spune un element va fi dimensiunea de un câine și am de gând să citesc de fapt, doi dintre ei. Alternativ, ceea ce am putea face este spun că sunt doar de gând să citesc un element și că un element va fi dimensiunea de doi câini. Deci, asta e analog cum puteți fel de joc în jurul valorii de cu dimensiunea și numărul de în funcție de ceea ce este mai mult intuitiv pentru tine. Bine. Deci, acum ajungem la fișiere de scriere. Când doriți să scrie un fișier, primul argument este, de fapt în cazul în care sunteți de lectură de la. Deci, asta e practic datele pe care aveți de gând să scrie în fișierul, care este indicatorul la sfârșitul. Așa că atunci când ai de a face cu PSET, asigurați-vă că nu obține confuz. Poate că au partea definiții, prin partea. Puteți trage definițiile în manualul de tastarea om și fwrite, apoi, de exemplu, în terminalul, sau puteți referi înapoi la acest diapozitiv și asigurați-vă că utilizați corect. Deci, din nou, pentru fwrite, atunci când aveți un fișier pe care doriți să scrie în, care va fi ultimul argument și că va fi un pointer la acel fișier. Deci asta e modul în care avem de a face cu scrierea, probabil, mai multe octeți la un moment dat, dar presupunem că doriți să scrieți doar în doar un caracter unic. După cum vom vedea mai târziu în acest exemplu, în bitmap vom avea de a utiliza asta. Asta e atunci când putem folosi fputc, în esență, pune doar un caracter la un moment dat, Chr, în pointerul fișierului, și asta e indicatorul nostru acolo. Deci ori de câte ori căutăm sau să scrie într-un fișier, fișierul este pastrarii unei piste unde suntem. Deci e un fel de cursor, poziția indicatorul fișierului. Și așa ori de câte ori scrie sau să citească din nou într-un fișier, fișierul de fapt, își amintește în cazul în care aceasta este, și astfel continuă de unde cursorul este. Acest lucru poate fi benefic, atunci când doriți, să zicem, citiți într-o anumită sumă pentru a face ceva și a citit apoi în următoarea sumă, dar, uneori, s-ar putea dori să se întoarcă sau de fapt, începe de la o anumită valoare de referință. Deci, atunci funcția fseek, ceea ce face este ne permite pentru a muta cursorul într-un anumit fișier un anumit număr de octeți. Și atunci ce trebuie să facem este specifica în cazul în care valoarea de referință este. Deci, fie că se deplasează înainte sau înapoi de unde cursorul prezent este, sau putem specifica faptul că acesta ar trebui să treacă doar de la începutul fișierului sau de la sfârșitul fișierului. Și astfel încât să puteți trece la valori negative sau pozitive la suma, și că va fel de a muta cursorul, fie înainte sau înapoi. Înainte de a intra în psets celelalte, orice întrebări pe fișier I / O? Bine. Așa cum am intra în mai multe exemple, nu ezitați să mă opresc pentru întrebări. Deci, în roman sau film polițist, ești dat un fișier de tip bitmap similar cu acesta roșu pe diapozitiv, si se pare ca asta - o grămadă de puncte roșii - și nu știi cu adevărat ce este scris. Dacă vă strabism, ați putea fi capabil de a vedea o culoare albastruie ușoară în interiorul mijloc. În esență, asta e în cazul în care textul este stocat. Nu a fost o crimă ce sa întâmplat, iar noi trebuie să aflăm cine a făcut-o. În scopul de a face acest lucru, avem nevoie de un fel de a converti această imagine într-un format lizibil. Dacă voi întâlnit vreodată acest lucru, uneori, nu ar fi kituri de mici în cazul în care v-ați putea avea o lupă cu un film roșu. Oricine? Da. Deci, v-ar fi ceva de mână ca asta, ar avea o lupă cu filmul roșu peste ea, v-ar pune peste imaginea, și v-ar fi capabil de a vedea mesajul ascuns acolo. Noi nu avem o lupă cu film rosu, astfel încât în ​​loc vom crea un fel de propriile noastre în acest PSET. Și astfel utilizatorul este de gând să roman sau film polițist de intrare, apoi indiciu,. Bmp, asa ca asta e infile, asta e mesajul red dot, și apoi ei spun verdict.bmp va fi outfile noastră. Deci, se va crea o imagine bitmap nou similar cu un indiciu cu excepția cazului în-un format lizibil unde putem vedea mesajul ascuns. Din moment ce am de gând să se ocupe cu editarea și manipularea bitmap de un anumit fel, vom arunca cu capul în fel de în structura acestor fișiere bitmap. Am trecut peste astea un pic cam în curs, dar să ne uităm în ele ceva mai mult. Bitmap sunt în esență, doar un aranjament de octeți în cazul în care am precizat care înseamnă octeți ce. Deci, aici este un fel de hartă a imaginii bitmap spunând că acesta începe cu unele fișiere antet, începe cu unele informații acolo. Veți vedea că la aproximativ 14 numarul octet dimensiunea este indicată de imagine bitmap, și continuă pe. Dar atunci ce suntem cu adevărat interesați și de aici se începe în jurul valorii de numărul de octet 54. Avem aceste triplete RGB. Ceea ce se întâmplă să faceți este să conțină pixeli reale, valorile de culoare. Tot mai sus că, în antetul este unele informații corespunzător dimensiunea imaginii, lățimea imaginii și înălțimea. Când mergem în umplutură mai târziu, vom vedea de ce dimensiunea imaginii ar putea fi diferită decât lățimea sau înălțimea. Deci, atunci pentru a reprezenta aceste - aceste imagini bitmap sunt secvențe de octeți - ceea ce am putea face este bine spune, am de gând să-mi amintesc că, la indicele de 14, asta e în cazul în care dimensiunea este, de exemplu, ci ceea ce am de gând să fac pentru a face acest lucru mai ușor este acesta incapsuleaza intr-o struct. Și astfel avem două struct făcute pentru noi, un BITMAPFILEHEADER și o BITMAPINFOHEADER, și așa ori de câte ori am citit în acest dosar, în mod implicit, va fi merge în ordine, și astfel, în ordinea în care, de asemenea, de gând să completeze în variabile, cum ar fi biWidth și biSize. Și apoi în cele din urmă, fiecare pixel este reprezentat de trei octeți. Primul este cantitatea de albastru, în pixeli, a doua este cantitatea de verde, și, în final, cantitatea de roșu, unde 0 este, în esență nici verde, albastru sau roșu sau nu o și apoi ff este valoarea maximă. Acestea sunt valori hexazecimale. Deci, dacă avem FF0000, apoi care corespunde valorii maxime a albastru si atunci nu mai verde și nu roșu, astfel încât atunci ne-ar da un pixel albastru. Apoi, dacă avem cu toții ff lui peste bord, atunci înseamnă că avem un pixel alb. Aceasta este un fel de opus de obicei atunci când spunem că RGB. Se întâmplă de fapt BGR. Deci, dacă ne uităm, de fapt într-un exemplu de imagine bitmap - lasa-ma sa o trag aici. E un mic mic. Sunt zoom in, și putem vedea e pixelated. Se pare ca blocuri de culoare. Ai blocuri albe și apoi blocuri de culoare roșie. Dacă joci în Microsoft Paint, de exemplu, ai putea face ceva de genul asta de fapt doar pictura pătrate anumite într-o anumită ordine. Deci, atunci ce acest lucru se traduce în bitmap este după cum urmează. Aici avem primul pixeli albi, că toate 6 sunt ai lui f, iar apoi avem pixeli roșii, indicată de 0000FF. Și astfel, secvența de octeți pe care le avem indică modul în care imaginea bitmap este de gând să uite. Deci, ceea ce am făcut aici este doar scris toate acele octeți și apoi colorate în roșu astfel încât să puteți vedea un fel de, dacă strabism un pic, modul în care indică un fel de o fata zambitoare. Modul în care locul de muncă bitmap imagini este practic l-am imagina ca o grilă. Și astfel în mod implicit, fiecare rand al grilei trebuie să fie un multiplu de 4 octeți. Dacă ne uităm la o imagine bitmap, pe care îl completați în fiecare valoare. De exemplu, este posibil să aveți un roșu aici, un verde aici, un albastru aici, dar trebuie să vă asigurați că imaginea este completat cu un multiplu de patru octeți. Deci, dacă vreau imaginea mea să fie de trei blocuri de larg, atunci mi-ar trebui să pună o valoare gol în ultima pentru a face un multiplu de patru. Așa că atunci aș adăuga în ceva care ne suni umplutură. Mă duc pentru a indica faptul că există cu un x. Acum spune dorim o imagine care este de 7 pixeli lung, de exemplu. Avem 1, 2, 3, 4, 5, 6, 7, și toate, care este umplut cu culoare. Modul în care imaginile bitmap lucra este că avem nevoie de un 8-a. Chiar acum avem 1, 2, 3, 4, 5, 6, 7. Avem nevoie de 8 locuri pentru imaginea bitmap pentru a citi corect. Deci ceea ce trebuie să faceți este să adăugați în doar un pic de umplutură pentru a vă asigura că toate lățimile sunt uniforme și că toate lățimile sunt un multiplu de 4. Și așa am indicat mai sus, padding ca x sau o linie de greu de descifrat, dar în imaginile reale bitmap padding este indicată cu un 0 hexazecimal. Deci, care ar fi un singur caracter, 0. Ce ar putea veni la îndemână este comanda xxd. Ceea ce face este de fapt vă arată, cum ar fi similar cu ceea ce am făcut înainte cu smiley De fapt, când am imprimat ce fiecare culoare ar fi pentru pixel și apoi cu ajutorul culorilor, atunci când rulați xxd cu următoarele comenzi, apoi îl va imprima de fapt, ce culorile sunt pentru acei pixeli. Ceea ce trebuie sa faci este aici eu indică, la fel ca s-54 spune că am de gând să înceapă de la octet 54 pentru că înainte de asta, amintiți-vă, dacă ne uităm înapoi la harta de bitmap-uri, asta e tot ce informațiile de antet și lucruri de genul asta. Dar ceea ce ne interesează cu adevărat este despre pixelii reale care indică culoarea. Deci, prin adăugarea în acest pavilion,-S 54, atunci suntem capabili de a vedea valorile de culoare. Și nu vă faceți griji cu privire la steagurile complicate și lucruri de genul asta. În spec. set de probleme, vei avea directii despre cum să utilizați xxd pentru a afișa pixeli. Deci, dacă vedeți aici, un fel de arata ca o cutie verde, acest lucru mic. Am culorilor, 00ff00 spunand ca practic nici albastru, o mulțime de verde, și nu roșu. Deci, care corespunde verde. După cum vedeți aici, vom vedea un dreptunghi verde. Acest dreptunghi verde este la numai 3 pixeli lățime, deci atunci ce trebuie să facem pentru a vă asigura că imaginea este un multiplu de 4 largi este să adăugați în padding suplimentare. Și astfel, atunci cum veți vedea aceste 0s aici. Acest lucru va fi de fapt rezultatul Redimensionare PSET dumneavoastră, luând în esență, bitmap mic și apoi majorându-se cu 4. Și astfel ceea ce vedem este că, de fapt această imagine este de 12 pixeli lățime, dar 12 este un multiplu de 4, și astfel avem de fapt, nu văd nici 0s la capăt, deoarece nu avem nevoie să adăugați orice deoarece este pe deplin căptușite. Ea nu are nici o cameră mai mult. Bine. Orice întrebări despre umplutură? Bine. Mișto. Așa cum am menționat mai înainte, bitmap-uri sunt doar o secvență de octeți. Și astfel ceea ce avem este loc de care au nevoie pentru a ține evidența exact ce număr de octet corespunde un element specific, de fapt, am creat o structura pentru a reprezenta. Deci, ceea ce avem este o struct RGBTRIPLE. Ori de câte ori aveți o instanță a unui triplu RGB, deoarece acesta este un tip de defini struct, atunci puteți accesa variabila rgbtBlue, În mod similar, variabilele verde și roșu, care va indica cat de mult albastru, verde, roșu și respectiv, ai. Deci, dacă avem variabila set albastru la 0, setul verde la FF, care este valoarea maximă poti avea, iar apoi variabila roșu setată la 0, atunci ce culoare ar prezenta special, RGB triplu reprezinta? >> [Elev] Verde. Verde. Exact. Acesta va fi util să știți că ori de câte ori aveți o instanță a unui triplu RGB, puteți accesa de fapt, cantitatea de culoare - albastru, verde și roșu - separat. Acum, că am vorbit despre structura pe care, haideți să aruncăm o privire la fișierul BMP. Acestea sunt făcute pentru tine struct. Aici avem o struct BITMAPFILEHEADER. De interes este dimensiunea. Mai târziu, avem antet informații, care are câteva lucruri care sunt mai interesante pentru noi, și anume dimensiunea, latimea, inaltimea si. Așa cum vom merge în mai târziu, atunci când ai citit in pentru a fișier, se citește în mod automat, deoarece ne-am stabilit pentru a fi la fel. Deci, biSize va conține octeți dreptul care corespund dimensiunea reală a imaginii. Și apoi aici, în cele din urmă, așa cum am vorbit despre, avem struct RGBTRIPLE typedef. Avem un rgbtBlue, verde, roșu și asociate cu ea. Mare. Bine. Acum, că am înțeles bitmap un pic, să înțelegeți că avem un antet fișier și un antet informatiile asociate cu acesta și apoi după aceea, avem lucruri interesante de culori, iar aceste culori sunt reprezentate de structs RGBTRIPLE, și cei, la rândul lor, au trei valori asociate albastru, verde, rosu si. Deci, acum, putem fel de Recuperare cred despre un pic. Scuze. Gândiți-vă la roman sau film polițist. Când avem fișierul nostru de idee, atunci ceea ce dorim să facem este să-l citesc în pixel cu pixel si apoi schimba cumva acei pixeli, astfel încât să putem scoate într-un format ușor de citit. Și așa să-l transmite, vom scrie pixel cu pixel în fișierul verdict.bmp. Asta e un fel de multe de făcut. Ne dăm seama că. Deci, ceea ce am făcut este de fapt am le-ați furnizat cu copy.c. Ce copy.c face este doar face o copie exactă a unui fișier de tip bitmap dat și apoi scoate-l. Deci, aceasta deschide fișierul deja pentru tine, citește în pixel cu pixel, și apoi scrie într-un fișier de ieșire într-. Să aruncăm o privire la asta. Aceasta este asigurarea utilizării adecvate, obtinerea de nume de fișiere aici. Ceea ce face este aceasta stabilește fișierul de intrare pentru a fi ceea ce am trecut în în infile aici, care este al doilea în linia de comandă argumentul. Controale pentru a vă asigura că putem deschide fișierul. Controale să vă asigurați că putem face o outfile nou aici. Atunci ce face asta aici, doar practic începe să citească pentru a fișier de tip bitmap de la început. Început, după cum știm, conține BITMAPFILEHEADER, și astfel acele secvențe de biți vor completa în mod direct în BITMAPFILEHEADER. Deci, ce avem aici este a spune că BF BITMAPFILEHEADER - asta e variabila noul nostru a BITMAPFILEHEADER tip - am de gând să pună în interiorul BF ceea ce am citit de la în pointer, care este infile noastră. Cât de mult am citit? Am citit în modul în care de multe bytes avem nevoie să conțină BITMAPFILEHEADER întreg. În mod similar, asta e ceea ce facem noi pentru antet informatii. Deci, suntem în continuare de-a lungul fișierul nostru în infile, și suntem citirea acestor biți și bytes, iar noi că le conectați direct în în aceste cazuri ale variabilelor pe care le faci. Aici suntem doar asigurându-vă că este un bitmap bitmap. Acum avem un outfile, nu? Deci, ca atare atunci când l-am crea, în esență, e gol. Deci avem de a crea de fapt un bitmap nou de la zero. Ceea ce facem este trebuie să ne asigurăm că vom copia în antetul fișierului și antet informații la fel ca infile are. Ceea ce facem este vom scrie - și amintiți-vă că BF este variabila BITMAPFILEHEADER de tip, astfel încât ceea ce facem noi este doar faptul că vom folosi conținut pentru a scrie în outfile. Aici, îți amintești că am vorbit despre umplutură, cum e important să vă asigurați că suma de pixeli pe care le avem este un multiplu de 4. Aceasta este o formulă destul de util pentru a calcula cât de mult ai umplutură având în vedere lățimea de fișier. Vreau ca voi să vă amintiți că, în copy.c avem o formulă de calcul umplutură. Bine? Deci, toată lumea minte asta. Mare. Deci, atunci ce face copy.c următoare este iterează peste toate scanlines. Ea trece prin primele rânduri și apoi stochează fiecare triplă că citește și apoi scrie în outfile. Deci aici suntem doar o lectură RGB triplu la un moment dat și punerea apoi că triplă aceleași în outfile. Partea mai dificila este faptul că padding nu este un triplet RGB, și astfel nu putem citi doar că valoarea umplutură de triplete RGB. Ceea ce trebuie să facem este de fapt doar să mutați indicatorul de poziția noastră fișierul, mutați cursorul nostru, la fel de săriți peste tot padding, astfel că suntem la rândul următor. Și apoi ce face asta este copia vă arată cum ar putea să doriți să adăugați padding. Deci am calculat cât de mult avem nevoie de umplutură, Asta înseamnă că avem nevoie de numărul de umplutură 0s. Ceea ce face este un pentru buclă care pune numărul de umplutură 0s în outfile nostru. Și apoi în cele din urmă, vă închideți ambele fișiere. Să închideți infile, precum și outfile. Deci asta e modul în care copy.c lucrări, și că va fi destul de util. De fapt, în loc de doar direct copierea și lipirea-l sau doar se uită la ea și să tastați în tot ce vrei, este posibil să doriți doar să execute această comandă în terminal, cp copy.c whodunit.c, ceea ce va crea un nou fișier, whodunit.c, care conține conținutul exact același ca și copie face. Deci, atunci ce putem face este folosi ca un cadru pe care să construiască și să editați pentru fișierul nostru roman sau film polițist. Acestea sunt noastră de a-DOS să facă pentru roman sau film polițist, dar ceea ce face copy.c este, de fapt are grijă de cele mai multe dintre ele pentru noi. Deci, tot ce trebuie să faci în continuare este să modificați pixeli după cum este necesar pentru a face de fapt fișierul poate fi citit. Amintiți-vă că, pentru un pixel dat triplu, asa ca pentru o variabilă dată de RGBTRIPLE tip, puteți accesa valorile albastru, verde și roșu. Care va veni la îndemână, deoarece în cazul în care aveți posibilitatea să le accesați, asta înseamnă că puteți verifica, de asemenea, le, și asta înseamnă că puteți schimba, de asemenea, le. Așa că atunci când ne-am dus înapoi la exemplul nostru roșu lupă, în esență, că a fost acționând ca un fel de filtru pentru noi. Deci, ceea ce dorim să facem este să vrem filtra toate tripletele care vin inch Există mai multe moduri diferite de a face acest lucru. Practic, poti avea orice tip de filtru dorit. Poate că doriți să schimbați toți pixelii rosii sau poate doriți să modificați un pixel de culoare diferită de o culoare diferită. Asta depinde de tine. Amintiți-vă că puteți verifica ce culoare pixelilor este și apoi puteți modifica, de asemenea, ca te duci prin intermediul. Bine. Deci asta e roman sau film polițist. Odată ce aveți o roman sau film polițist, veți ști cine vinovat de crimă a fost. Acum vom merge la Resize. Vom fi în continuare de-a face cu bitmap-uri. Ceea ce am de gând să faci este vom avea un bitmap de intrare iar apoi vom trece într-un număr și apoi obține un bitmap outfile în cazul în care este practic infile nostru scalate de n. Spune dosarul meu a fost doar un pixel mare. Apoi, dacă n meu a fost de 3, scalare cu 3, atunci aș repeta că n pixeli număr de ori, SO 3 ori, iar apoi, de asemenea, scară-l jos de 3 ori la fel de bine. Deci, vedeți voi că extinderea vertical, cât și orizontal. Și apoi aici este un exemplu. Dacă aveți n = 2, veți vedea că primul pixel albastru acolo repetate de două ori orizontal, precum și de două ori pe verticală. Și apoi continuă pe care, și așa aveți o scalare directă a imaginii originale de către doi. Deci, dacă ar fi să detaliat pseudocod pentru aceasta, dorim să deschideți fișierul. Și apoi, știind că, dacă ne întoarcem aici, vedem că lățimea de outfile va fi diferit decât lățimea de infile. Ce înseamnă asta? Asta înseamnă că informațiile noastre antet se va schimba. Și deci ce vom dori să faceți este să actualizeze informatiile antet, știind că atunci când citim în fișierele dacă sunteți de operare pe cadru copy.c, avem deja o variabila care indică ceea ce este dimensiunea și lucruri de genul asta. Deci, odată ce ați că, ceea ce ar putea să doriți să faceți este să schimbe aceste variabile speciale. Amintiți-vă, dacă aveți un struct, modul în care accesați variabilele din asta. Puteți utiliza operatorul punct, nu? Deci folosind asta, știți că veți avea nevoie pentru a schimba informatii antet. Deci, aici e doar o listă a elementelor reale care vor să se schimbe în fișierul. Dimensiunea fișierului este de gând să se schimbe, imaginea, precum și lățimea și înălțimea. Deci, apoi merge înapoi la harta de bitmap-uri, uita-te la ea, dacă e antetul fișierului sau antet care conține informații că informațiile și apoi modificați după cum este necesar. Din nou, spun cp copy.c resize.c. Asta înseamnă că acum resize.c conține tot ceea ce este conținut în interiorul copie pentru că ne oferă o copie mod de a citi în fiecare pixel pentru a scanline cu pixel. Cu excepția acum, în loc de a schimba doar valorile așa cum am făcut-o în roman sau film polițist, ceea ce dorim să facem este vrem să scrie în pixeli mai multe atâta timp cât n nostru este mai mare decât 1. Atunci, ce vrem să facem este vrem să-l întindă orizontal cu n, precum și întinde pe verticală cât de n. Cum am putea face acest lucru? Spune n este 2 și aveți această infile dat. Cursorul este de gând să înceapă de la prima, și ceea ce vrei să faci în cazul în care n este 2, pe care doriți să imprimați în 2 din cele. Deci, să imprimați în 2 din cele. Apoi, cursorul se va muta la următoarea pixeli, care este rosie, și se va imprima 2 din acelea rosii, adaugarea se pe ceea ce se face înainte. Apoi, cursorul se va muta la următoarea pixel și să tragă în 2 din cele. Dacă te uiți înapoi la cadrul copy.c, ce face asta chiar aici se creează o nouă instanță a unui triplet RGB, o nouă variabilă numită triplu. Și aici, atunci când citește în ea, citește de la infile 1 RGBTRIPLE și îl stochează în interiorul acelei variabile triplu. Deci, atunci aveți de fapt, o variabilă care reprezintă acel pixel special. Apoi, când scrii, ceea ce ar putea să doriți să faceți este să incadrati declarația fwrite într-o buclă de că scrie în outfile dumneavoastră ori de câte ori este nevoie. Asta e destul de simplu. Doar repeta practic procesul de scriere n numărul de ori să-l scară orizontală. Dar apoi trebuie să ne amintim că padding noastră se va schimba. Anterior, spune că am avut ceva de lungime 3. Apoi, ne-ar adăuga doar în cât de mult umplutură? Doar un singur mai mult pentru a face un multiplu de 4. Dar spun suntem scalarea această imagine special prin n = 2. Deci, atunci numarul de pixeli albaștri ne-ar avea la sfârșitul anului? Ne-ar avea 6. 1, 2, 3, 4, 5, 6. Bine. 6 nu este un multiplu de 4. Care e cel mai apropiat multiplu de 4? Asta va fi 8. Deci, de fapt, vom avea 2 caractere de umplutură acolo. Are cineva aminte dacă avem o formulă pentru a calcula padding și în cazul în care ar putea fi? [Imperceptibil elev de răspuns] >> Da, copy.c. Corect. Există o formulă în copy.c pentru a calcula cât de mult ai umplutură dat o lățime special de imagine bitmap. Deci, atunci care va fi util atunci când aveți nevoie să adăugați într-o anumită sumă de umplutură să dau de fapt seama cât de mult padding trebuie să adăugați. Dar într-o notă, totuși, este că doriți să vă asigurați că sunteți folosind mărimea potrivită. Trebuie doar să fiți atenți, pentru că tu ești de fapt de gând să se ocupe cu două imagini bitmap. Doriți să vă asigurați că sunteți folosind dreptul de unul. Când sunteți calcularea padding pentru outfile, pe care doriți să utilizați lățimea outfile și nu lățimea anterior. Mare. Acest tip de stretching are grija de o imagine bitmap ansamblu orizontal. Dar ceea ce vrem să facem este de fapt întinde pe verticală, precum și. Acest lucru se întâmplă să fie un pic mai complicată pentru că atunci când ne-am terminat de copiat un rând și scris că rand, cursorul nostru va fi la sfârșitul anului. Deci, dacă am citit din nou, apoi se doar de gând să citesc în la linia următoare. Deci, ceea ce dorim să facem este un fel de găsi o modalitate de a copia aceste rânduri din nou sau doar un fel de a lua acel rând și apoi rescrierea din nou. Așa cum am un fel de aluzie la, există mai multe moduri diferite de a face acest lucru. Ce ai putea face este ca te duci prin citirea și prin scanline special și modificarea acesteia, după caz, apoi un fel de magazin toate aceste pixeli într-o matrice. Apoi, mai târziu, pe știți că veți avea nevoie pentru a imprima ca matrice din nou, și astfel încât să puteți utiliza doar că matrice pentru a face asta. Un alt mod de a face acest lucru este de ai putut copia în jos cu un rând, Înțeleg că aveți nevoie să copiați din nou, astfel muta cursorul de fapt, și care va fi folosind metoda fseek. Ai putea muta cursorul tot drumul înapoi și apoi repetați procesul de copiere din nou. Deci, în cazul în care numărul nostru de scalare este n, atunci cum de multe ori ne-ar trebui să ne întoarcem și rescrie o linie? >> [Elev] n - 1. Da >>, perfectă. n - 1. Am făcut-o deja o dată, astfel încât, atunci vom dori să repetați procesul de întoarcere n - 1 valoarea de ori. Bine. Deci nu aveți funcția de redimensionare. Acum putem ajunge la o parte foarte distractiv, PSET meu favorit, care este Recover. În loc de bitmap-uri, de data aceasta avem de-a face cu JPEG. Noi nu suntem de fapt un fișier dat doar de JPEG, suntem de fapt o primă dat format de card de memorie. Și astfel această contine un pic de valori și informații de gunoi la început, si apoi incepe si el are o grămadă de fișiere JPEG. Cu toate acestea, suntem înmânat o carte în care am șters fotografiile; în esență, ne-am uitat în cazul în care fotografiile sunt situate în carte. Deci, atunci sarcina noastră în Recover este de a merge prin acest format de cartelă și de a găsi acele poze din nou. Din fericire, structura de fișiere JPEG și fișiere carte este un pic de ajutor. Este cu siguranta ar fi fost un pic mai complicată în cazul în care nu au fost în acest format special. Fiecare fișier JPEG de fapt, începe cu două secvențe posibile, enumerate mai sus. Practic, ori de câte ori aveți un nou fișier JPEG, începe fie cu secvența ffd8 ffe0 sau altul, ffd8 ffe1. Un alt lucru util de știut este faptul că JPEG sunt stocate culorile. Deci, ori de câte ori un fișier JPEG se termină, celălalt începe. Deci, nu există nici un fel de în-între valorile de acolo. Odată ce te-a lovit începutul unui JPEG, dacă ați fost deja citit un fișier JPEG, știi că ai lovit la sfârșitul celui anterior și începutul celui următor. Pentru a vizualiza acest fel de, am făcut o schematică. Un alt lucru despre JPEG este că le putem citi în secvențe de 512 octeți, la un moment dat, în mod similar cu începutul cardului. Noi nu trebuie să fie verificarea fiecare octet unic, pentru că asta ar suge. Deci, în loc, ceea ce putem face este de fapt doar citesc în 512 octeți la un moment dat și apoi, în loc de check-in între cei în aceste felii mici mici, putem verifica doar începutul 512 bytes. În esență, în această imagine, ceea ce vezi este la începutul cardului, aveți valori care nu sunt cu adevărat relevante pentru JPEG reale. Dar atunci ce am este o stea pentru a indica unul dintre cele două secvențe de pornire pentru un JPEG. Deci, ori de câte ori vedeți o stea, știți că aveți un fișier JPEG. Și apoi fiecare fișier JPEG este de gând să fie un multiplu de 512 octeți dar nu neapărat multiplu aceeași. Modul în care știți că v-ați lovit un alt JPEG este dacă te-a lovit o altă stea, o altă secvență de pornire de octeți. Atunci ceea ce avem aici este aveti roșu fișier JPEG continuă până când te-a lovit o stea, care este indicată printr-o culoare nouă. Veți continua si apoi te-a lovit o altă stea, te-a lovit un alt JPEG, vei continua tot drumul până la sfârșitul anului. Ești la ultima fotografie aici, roz. Te duci la capăt până când te-a lovit la sfârșitul fișierului de caracter. Acest lucru se întâmplă pentru a fi cu adevărat utile. Câteva takeaways principale aici: Fișier carte nu începe cu un fișier JPEG, dar o dată JPEG începe, toate imaginile JPEG sunt stocate alături unul de altul. Unii pseudocod pentru Recover. În primul rând, vom deschide fișierul nostru carte, și care va fi cu ajutorul fișierului de I / O funcții. Vom repeta procesul până când următorul am ajuns la sfârșitul fișierului. Vom citi 512 octeți la un moment dat. Și ceea ce am spus aici este că o să-l stocați într-un tampon, Deci, practic stai la aceste 512 octeți până nu știm exact ce să facă cu ele. Atunci, ce vrem să facem este vrem să verificați dacă ne-am lovit o stea sau nu. Dacă ne-am lovit o stea, în cazul în care ne-am lovit pe unul dintre secvențele de pornire, atunci știm că ne-am lovit de un nou fișier JPEG. Ceea ce vom dori să faceți este să ne gând să doriți să creați un fișier nou în directorul nostru pset4 pentru a continua să faceți acel fișier. Dar, de asemenea, dacă ne-am făcut deja un JPEG înainte, Apoi vrem să se încheie cu acel fișier și împingeți-l în folderul pset4, în cazul în care vom avea acel fișier stocat pentru că dacă nu se specifică faptul că am terminat acel fișier JPEG, atunci vom avea practic o sumă nedeterminată. Cele JPEG nu se va termina. Deci, vrem să ne asigurăm că, atunci când suntem într-lectură într-un fișier JPEG și scris, vrem să închidă în mod expres că, în scopul de a deschide urmatorul. Vom dori pentru a verifica mai multe lucruri. Dorim să verifice dacă suntem la începutul unui nou JPEG cu tampon nostru și, de asemenea, în cazul în care deja am găsit o JPEG înainte de pentru că se va schimba procesul de ușor. Deci dupa ce trece prin tot drumul și te-a lovit la sfârșitul fișierului, atunci ceea ce veți dori să faceți este să vă veți dori să închideți toate fișierele care sunt deschise în prezent. Asta va fi, probabil, ultimul fișier JPEG pe care o ai, precum și fișierul cardul pe care le-ați avut de a face cu. Ultimul obstacol de care avem nevoie pentru a aborda este modul de a face de fapt un fișier JPEG și cum pentru a împinge de fapt la dosar. PSET cere ca fiecare JPEG pe care le găsiți fie în următorul format, în cazul în care aveți numărul. jpg. Numărul, chiar daca e 0, numim aceasta 000.jpg. Ori de câte ori veți găsi un fișier JPEG în program, ai de gând să doriți să-l numească, în ordinea în care se gaseste. Ce înseamnă? Avem nevoie de un fel de a ține evidența cât de multe am gasit și ce numărul fiecărui JPEG ar trebui să fie. Aici am de gând să profite de funcția sprintf. Similar cu printf, care doar un fel de printuri o valoare afară, în terminal, imprimă sprintf fișierul afară, în folderul. Și deci ce-ar face dacă am avut sprintf, titlul, iar apoi șirul acolo, s-ar imprima 2.jpg. Presupunând că am închis fișierele mele în mod corect, , care să conțină fișierul pe care am fost scris afară. Dar un lucru este faptul că cod pe care am aici nu satisface destul de ceea ce PSET cere. PSET cere ca al doilea fișier JPEG ar trebui să fie numit 002 în loc de doar 2. Deci, atunci când imprimați numele, atunci, probabil, ați putea dori să-și modifice substituent ușor. Are cineva aminte cum ne permite spații suplimentare atunci când am imprima ceva? Da. >> [Elev] Ai pus un 3 între semnul procent și 2. Da >>, perfectă. Vei pune un 3 în acest caz, pentru ca vrem spatiu pentru 3. 3d% ar da probabil 002.jpg în loc de 2. Primul argument în funcția sprintf este de fapt o matrice char, pe care am cunoscut anterior ca siruri de caractere. Cei voință, un fel de mult ca un depozit temporar, stoca doar șirul rezultat. Tu nu va fi într-adevăr de-a face cu acest lucru, dar trebuie să-l includă. Știind că fiecare nume de fișier are număr, care preia trei caractere, și apoi jpg,. cât timp ar trebui să fie această matrice? Arunca un număr. Câte caractere în titlu, în numele? Deci, nu e 3 hashtag-uri, perioada, jpg. >> [Elev] 7. >> 7. Nu este destul. Am de gând să doriți 8 pentru că vrem să permită Terminator nul, de asemenea. În cele din urmă, doar pentru a scoate procesul pe care îl veți face pentru Recover, aveți vreo informație început. De a continua până când veți găsi la începutul unui fișier JPEG, și care poate fi fie una din cele două secvențe minime orientative. Vă păstrați la lectura. Fiecare bară reprezintă aici 512 octeți. Vă păstrați la lectura, ține la lectura până când vă confruntați cu o altă secvență de pornire. Odată ce ați că, ajungi curent JPEG - în acest caz, e roșu, așa că vă doriți să se încheie asta. Vrei să sprintf numele pe care în folderul pset4, atunci când doriți să deschideți un nou JPEG și apoi să păstreze la lectura până când vă confruntați cu următoarea. Păstrați la lectura, ține la lectura, și apoi în cele din urmă, în cele din urmă, ai de gând să ajungă la sfârșitul fișierului, și așa veți dori să închidă ultimul JPEG care au fost de lucru cu, sprintf că în folderul pset4, si uita-te apoi la toate imaginile pe care le-ați primit. Aceste imagini sunt de fapt imagini ale personalului CS50, și astfel acest lucru este în cazul în care partea distractivă bonus de PSET vine în este că sunteți în competiție în secțiunile dvs. pentru a găsi TFS în imagini și a face fotografii cu ei pentru a dovedi că ai făcut PSET și astfel încât să puteți vedea care membrii personalului sunt în imagini. Deci, atunci luați fotografii cu personalul. Uneori, va trebui să-i alunge jos. Probabil unii dintre ei vor încerca să fugă de la tine. Faci poze cu ei. Acest lucru este în curs de desfășurare. Nu e din cauza atunci când PSET este datorată. Termenul va fi anunțată în spec.. Apoi, împreună cu secțiunea dumneavoastră, în funcție de secțiunea ia cele mai multe imagini cu majoritatea membrilor personalului va câștiga un premiu destul de minunat. Asta e un fel de stimulent pentru a obține dvs. de pset4 terminat cât mai repede posibil pentru că atunci puteți obține la afaceri vânătoare în jos toți membrii personalului CS50 diferite. Asta nu e obligatoriu, deși, astfel încât odată ce veți obține imagini, atunci ați terminat cu pset4. Și am terminat cu Walkthrough 4, astfel încât vă mulțumesc tuturor pentru venit. Noroc cu criminalistica. [Aplauze] [CS50.TV]