[Powered by Google Translate] [Opis przejścia - Set Problem 4] [Zamyla Chan - Harvard University] [To jest CS50. - CS50.TV] Dobrze. Witam wszystkich i zapraszamy do Walkthrough 4. Dziś nasza pset jest Forensics. Sądownictwo jest naprawdę zabawne pset która polega czynienia z plików bitmapowych aby odkryć kto popełnił zbrodnię. Następnie jedziemy do rozmiaru kilku bitmap, to mamy również zamiar poradzić sobie z naprawdę zabawnej części zwanej Recover, , w którym jesteśmy w zasadzie podał kartę pamięci w których ktoś przypadkowo usunięte wszystkie swoje pliki, i jesteśmy proszeni o odzyskanie tych plików. Ale najpierw, zanim dotrzemy do PSET, naprawdę tylko chcę pogratulować wszystkim. Zaraz się w połowie kursu. Quiz 0 jest już za nami, a my jesteśmy w pset4, więc zasadniczo, jesteśmy w połowie drogi. Mamy długą drogę, jeśli spojrzeć do psets, pset0 i pset1, Gratuluję więc pod uwagę, że i mamy zamiar dostać się do niektórych rzeczy naprawdę zabawne. Więc nasz przybornik do tego Pset znowu zamiast poleceniem sudo yum-y aktualizacji jesteśmy w stanie po prostu uruchomić update50 jeśli jesteś w wersji 17.3 lub nowszej z urządzenia. Więc należy uruchomić update50 - to dużo łatwiejsze, kilka mniej znaków - upewnić się, że jesteś w najnowszej wersji urządzenia. Szczególnie ważne jest, aby update50 kiedy zacząć używać CS50 Check. Więc upewnij się, że możesz to zrobić. Dla wszystkich sekcjach w tym zbior, będziemy mieć do czynienia z plików wejściowych i wyjściowych, plik I / O. Będziemy się iść przez wiele programów, które zajmują się tablicami wskazując na pliki i tego typu rzeczy, więc chcemy się upewnić, że naprawdę jesteśmy zaznajomieni i wygodne do czynienia z, jak wejścia i wyjścia na plikach. W kodzie dystrybucji tego pset jest plik o nazwie copy.c, i to, co mamy zamiar znaleźć będzie bardzo przydatne dla nas bo będziemy do końca się faktycznie kopiowanie copy.c plik i tylko lekko zmiany, aby móc uzyskać pierwsze 2 części zestawu problemu. I tak to, jak już wspomniałem wcześniej, mamy do czynienia z bitmapami oraz JPEG. Tak naprawdę zrozumienie struktury, jak te pliki są zorganizowane, jak naprawdę możemy przetłumaczyć 0s i 1s w elemencie i rzeczy, które możemy rzeczywiście zrozumieć i zinterpretować i edytować, , które będzie bardzo ważne, więc wchodząc plików JPEG i bitmapowych i zrozumienia struktury tych. Pset4 jak zwykle zaczyna się od części pytania. Będą zajmować pliku I / O i Ci przyzwyczajeni do tego. Następnie część 1 jest Whodunit, w którym dostaniemy plik bitmapy , który wygląda trochę jak czerwone kropki na całym ciele. A potem po prostu to, co zamierzamy zrobić, to ten plik i tylko lekko go edytować w wersji, że możemy czytać. Zasadniczo, po zakończeniu prac, będziemy mieli ten sam plik chyba, że ​​będziemy w stanie zobaczyć ukrytą wiadomość ukryta przez tych wszystkich kropek czerwonych. Następnie Resize to program, podany plik , a następnie z uwagi na nazwę pliku, który wyprowadza a następnie otrzymuje numer, jak również, będzie faktycznie zmienić rozmiar tej bitmapy przez to wartość całkowitą. Potem wreszcie mamy Pset odzyskać. Dane są karty pamięci, a następnie muszą odzyskać wszystkie zdjęcia przypadkowo usunięte ale jak nie dowiemy się, właściwie usunięte i usunięte z pliku; właśnie rodzaju porażka, gdzie byli w pliku, ale mamy zamiar odzyskać to. Great. Więc idzie do pliku I / O w szczególności, są to cała lista funkcji, które będziesz używać. Widziałeś już trochę podstaw fopen, fread i fwrite, ale będziemy szukać dalej do jakiegoś pliku funkcje I / O takie jak fputc, w którym można po prostu napisać jeden znak na raz, fseek, gdzie można trochę przesunąć wskaźnik pozycji pliku w przód iw tył, I jeszcze kilka innych. Ale będziemy wchodzić, że nieco później podczas PSET. Więc po pierwsze, po prostu dostać się do pliku I / O, zanim pójdziemy do PSET, otworzyć plik, na przykład, co musisz zrobić, to faktycznie ustawić wskaźnik do tego pliku. Więc mamy wskaźnik pliku *. W tym przypadku, dzwonię to w wskaźnik, ponieważ to będzie mój plik_we. I tak mam zamiar użyć funkcji fopen, a następnie nazwę pliku i tryb, w którym będę mieć do czynienia z plikiem. Więc nie ma "r" w tym przypadku do czytania, "w", do pisania, a następnie "" dla dopisywania. Na przykład, gdy masz do czynienia z INFILE i wszystko, co chcesz zrobić, to odczytać bity i bajty zapisane tam, wtedy pewnie będzie chciał użyć "r" jako tryb. Gdy chcesz właściwie napisać, niby zrobić nowy plik, to co mamy zamiar zrobić, to mamy zamiar otworzyć nowy plik i używać "w" tryb do zapisu. Więc gdy jesteś rzeczywiście czytanie do plików, struktura jest następująca. Najpierw to wskaźnik do struktury, która będzie zawierać bajtów, które czytasz. Tak, że będzie to lokalizacja Koniec bajtów czytasz. Jesteś wtedy zamiar podać wielkość, jak w zasadzie ile bajtów Twój program powinien czytać w pliku, rozmiar zasadniczo jednym elementem, a masz zamiar określić, ile elementów chcesz przeczytać. I w końcu, trzeba wiedzieć, gdzie czytasz z, tak, że to będzie Twój na wskaźnik. I kolorami te, ponieważ fread jest również bardzo podobny do fwrite, chyba chcesz się upewnić, że używasz odpowiedniej kolejności, upewnij się, że jesteś rzeczywiście zapisu i odczytu z prawego pliku. Tak jak poprzednio, a następnie, jeśli mają rozmiar elementu, jak i liczbę elementów, wtedy możemy grać tu trochę. Powiedz, mam struct pies i tak to chcę czytać dwa psy na raz. Co mogłem zrobić, to powiedzieć rozmiar jednego elementu będzie wielkość jednego psa i będę rzeczywiście przeczytać dwa. Ewentualnie, co mogłem zrobić, to powiedzieć, że jestem po prostu się czytać jeden element i że jednym z elementów będzie wielkość dwóch psów. Więc to jest analogiczne jak można trochę poeksperymentować z wielkości i liczby w zależności od tego, co jest bardziej intuicyjna dla Ciebie. Dobrze. Więc teraz mamy do plików pisania. Gdy chcesz zapisać plik, pierwszy argument jest w rzeczywistości, gdzie czytasz od. Tak, że w zasadzie dane, które masz zamiar napisać do pliku które jest z wskaźnik na końcu. Tak więc, gdy masz do czynienia z PSET, upewnij się, że nie gubi. Może mieć obok definicji siebie. Można wyciągnąć definicje w instrukcji wpisując człowieka i fwrite, na przykład, w terminalu, czy można powrócić do tego slajdu i upewnij się, że używasz właściwego. Więc jeszcze raz, dla fwrite, gdy masz plik, który chcesz dodać do, , że będzie to ostatni argument i że będzie to wskazówka do tego pliku. Więc to jest to, jak radzimy sobie z pisaniem może kilka bajtów na raz, ale, że chcesz po prostu napisać w jednym znaku pojedynczym. Jak zobaczymy później, w tym przykładzie, w bitmap musimy użyć. To kiedy możemy użyć fputc zasadniczo tylko wprowadzenie jeden znak na raz, chr, do wskaźnika pliku, a to nasz wskaźnik tam. Tak więc, gdy szukamy lub zapisu w pliku, Plik jest śledzenie, gdzie jesteśmy. Więc jest to rodzaj kursora, wskaźnika pozycji w pliku. I tak zawsze, kiedy pisać lub czytać ponownie do pliku, plik rzeczywiście pamięta, gdzie to jest, i tak dalej, z której znajduje się kursor. Może to być korzystne, jeśli chcesz, na przykład, czytać w pewnym coś zrobić i odczytu w poniższej kwoty ale czasami możemy chcieć wrócić i zacząć od pewnej wartości referencyjnej. Więc funkcja fseek, co robi jest pozwala przesuwać kursor w określonym pliku pewna liczba bajtów. A potem to, co musimy zrobić, to określić, gdzie wartość referencyjna jest. Więc albo porusza się do przodu lub do tyłu, skąd kursora, lub można określić, że powinno poruszać się tylko na początku pliku lub koniec pliku. I tak można przekazać w wartości ujemne lub dodatnie do kwoty i że będzie trochę przesunąć kursor do przodu lub do tyłu. Zanim przejdziemy do innych psets, wszelkie pytania na temat pliku I / O? Okay. Jak dostać się do innych przykładów, nie wahaj się mnie zatrzymać na pytania. Więc w kryminał, jesteś wręczył bitmapy podobną do tej czerwonej na slajdzie, i wygląda to tak - kilka czerwonych kropek - i naprawdę nie wiem, co jest napisane. Jeśli zez, możesz być w stanie zobaczyć nieznaczny niebieskawy kolor wewnątrz środku. Zasadniczo, to gdzie tekst jest przechowywany. Nie było morderstwo, co się stało, i musimy dowiedzieć się, kto to zrobił. Aby to zrobić, musimy trochę przekonwertować ten plik na format czytelny. Jeśli faceci kiedykolwiek spotkałem to, czasami nie będzie małe zestawy gdzie masz lupę z czerwonej folii. Ktokolwiek? Tak. Zatem będziesz ręką coś takiego, to masz lupę z czerwoną folią nad nim, można umieścić go na obrazie, i może być w stanie zobaczyć wiadomość ukryta w nim. Nie mamy szkło powiększające z czerwoną folią, więc zamiast będziemy rodzaj stworzyć własne w tym zbior. I tak użytkownik będzie whodunit wejściowe, a następnie pojęcia,. Bmp, tak że jest plik_we, to czerwony komunikat dot, a potem mówią verdict.bmp będzie nasza outfile. Tak to się dzieje, aby utworzyć nowy obraz bitmapowy podobny do pojęcia jeden wyjątkiem w czytelnym formacie, gdzie możemy zobaczyć ukrytą wiadomość. Ponieważ będziemy mieć do czynienia z edycji i manipulacji bitmap pewnego rodzaju, będziemy rodzaju nurkowania w do struktury tych plików bitmapowych. Poszliśmy nad tymi trochę mało w wykładzie, ale spójrzmy na nich trochę więcej. Bitmapy są zasadniczo tylko układ bajtów gdzie mamy określony, które bajty oznaczają co. Więc tutaj jest trochę jak z mapą bitmapy mówiąc, że zaczyna się od niektórych plików nagłówkowych, zaczyna niektóre informacje tam. Widać, że w około 14 bajtów liczby rozmiar wskazuje na bitmapy, i nadal się. Ale co tak naprawdę interesuje tu zaczyna wokół bajtowej liczby 54. Mamy te trójek RGB. Co się dzieje, że do zrobienia jest zawierać rzeczywistych pikseli, wartości kolorów. Wszystko powyżej, że w nagłówku jest kilka informacji odpowiada wielkości obrazu, szerokość obrazu, i wysokości. Kiedy idziemy do obicia później zobaczymy dlaczego rozmiar obrazka mogą być inne niż szerokości i wysokości. Więc do reprezentowania tych - te bitmapy są ciągami bajtów - co możemy zrobić, to powiedzieć, dobrze, będę pamiętać, że w indeksie 14, to, gdzie rozmiar jest, na przykład, ale zamiast tego, co zamierzamy zrobić, aby to ułatwić jest ująć go w struktury. A więc mamy dwa przypisać struktury stworzone dla nas, BITMAPFILEHEADER i BITMAPINFOHEADER, i tak, gdy czytamy w tym pliku, domyślnie będzie to będzie w porządku, i tak w porządku to też będzie wypełnić do zmiennych takich jak biWidth i biSize. I w końcu, każdy piksel reprezentuje trzy bajty. Pierwszym z nich jest ilość niebieskiego piksela, drugi ilość zieleni I w końcu, ilość czerwonych, gdzie 0 jest zasadniczo nie ma zielone niebieskie lub czerwone lub nie ff i maksymalną wartość. Są to wartości szesnastkowe. Więc jeśli mamy FF0000, to odpowiada maksymalnej ilości niebiesko a nie zielony i nie czerwony, więc wtedy, że nam się niebieski piksel. Następnie, jeśli mamy FF całej płyty, to znaczy, że mają biały piksel. Jest to rodzaj przeciwieństwie do zwykle, kiedy mówimy, RGB. To się naprawdę dzieje BGR. Jeśli więc faktycznie spojrzeć przykład bitmapy - pozwól mi wyciągnąć jeden tutaj. To jest trochę małe. Jestem powiększanie, i widzimy to piksele. To wygląda jak bloki koloru. Masz białe bloki, a następnie czerwone bloki. Jeśli grasz w Microsoft Paint, na przykład, można zrobić coś takiego by w zasadzie tylko malowanie niektórych kwadratów w określonej kolejności. Tak więc to, co przekłada się w mapie bitowej jest następujący. Tutaj mamy pierwszy biały piksele, że wszystkie 6 są f-tych, a następnie mamy czerwone piksele, wskazany przez 0000FF. I tak sekwencji bajtów, które musimy wskazuje obraz bitmapowy będzie wyglądać. Więc to, co zrobiłem tutaj jest tylko napisane te wszystkie bajty, a następnie barwione w czerwony tak, że można trochę zobaczyć, jeśli zez trochę, jak tego rodzaju wskazuje na buźkę. Sposób, że obraz bitmapowy praca jest mi wyobrazić sobie, że w zasadzie w postaci siatki. I tak domyślnie, każdy wiersz siatki musi być wielokrotność 4 bajtów. Jeśli spojrzymy na obraz bitmapowy, jesteś wypełnienie każdej wartości. Na przykład, możesz mieć tu czerwony, zielony tu, niebieski tutaj, ale musisz upewnić się, że obraz jest wypełniona wielokrotności czterech bajtów. Więc jeśli chcę mój obraz, aby być trzy bloki szerokości, to chciałbym umieścić pustą wartość w tej ostatniej, aby to przez cztery. Więc chciałbym dodać w coś, co my wywołującego dopełnienie. Idę tylko do wskazania, że ​​tam z x. Teraz, że chcemy obraz o 7 pikseli długo, na przykład. Jest 1, 2, 3, 4, 5, 6, 7, i wszystko to jest wypełnione kolorem. Sposób, że bitmapy pracy jest to, że musimy 8.. W tej chwili mamy 1, 2, 3, 4, 5, 6, 7. Musimy 8 przestrzenie dla bitmapy, aby przeczytać poprawnie. Tak więc to, co mamy zrobić, to dodać tylko trochę wyściółki aby upewnić się, że wszystkie są jednolite szerokościach oraz, że wszystkie są szerokości przez 4. I tak wcześniej wskazano, wypychanie jako x lub falowane linii, ale w rzeczywistych obrazów bitmapowych wyściółka jest wskazywany przez 0 szesnastkowym. Więc to będzie pojedynczy znak, 0. Co może się przydać jest xxd polecenia. Co robi jest rzeczywiście pokazuje, jak podobne do tego, co robiłem wcześniej z buźki kiedy faktycznie wydrukowane, co każdy kolor będzie dla piksela i kolorami to po uruchomieniu xxd z następujących poleceń, wtedy rzeczywiście wydrukować co kolory są dla tych pikseli. Co trzeba zrobić, to tutaj wskazać, podobnie jak 54-s mówi, że mam zamiar rozpocząć na 54. bajcie bo przed tym, należy pamiętać, jeśli spojrzymy na mapę z map bitowych to wszystko informacje nagłówka i rzeczy w tym stylu. Ale to, co naprawdę dbają o to rzeczywiste piksele, które wskazują na kolor. Tak więc, dodając w tym flagi-s 54, to jesteśmy w stanie wyświetlić wartości kolorów. I nie martw się o skomplikowanych flag i tego typu rzeczy. W specyfikacji zestaw problemów, będziesz miał wskazówek co do sposobu korzystania xxd do wyświetlania pikseli. Więc jeśli tu widzisz, to niby wygląda na zielonym polu, to coś mały. I już kolorami w 00FF00 jako zasadniczo mówiąc nie niebieski, dużo zieleni, a nie czerwony. Tak, że odpowiada na zielony. Jak widać tutaj, widzimy zielony prostokąt. Ten zielony prostokąt jest tylko 3 pikseli szerokości, tak to, co mamy do zrobienia aby upewnić się, że obraz jest wielokrotnością 4 szerokości, to dodać w dodatkowym obiciem. I tak to jest to, jak widzisz te 0s tutaj. To rzeczywiście będzie wynik Twojej Pset Resize, zasadniczo biorąc małą bitmapę, a następnie rozszerzenie go przez 4. A więc to, co widzimy, jest to, że w rzeczywistości ten obraz jest 12 pikseli szerokości, ale 12 jest wielokrotnością 4, i tak naprawdę nie widzę żadnych 0s na końcu, bo nie trzeba już dodawać ponieważ jest w pełni wyściełane. To nie ma żadnych więcej miejsca. Okay. Wszelkie pytania dotyczące dopełnienia? Okay. Cool. Jak już wspomniano wcześniej, bitmapy są tylko ciąg bajtów. A więc to, co mamy, to zamiast konieczności śledzić dokładnie który to numer bajtu odpowiada do określonego elementu, faktycznie stworzyli struct do reprezentowania tego. Więc co mamy jest RGBTRIPLE struct. Gdy masz instancję RGB potrójne, ponieważ jest to typ zdefiniować struct, a następnie można przejść do rgbtBlue zmienną, Podobnie zielone i czerwone zmienne, które wskazują, jak bardzo niebieski, zielony, czerwony, odpowiednio, masz. Więc jeśli mamy niebieski zestaw zmienną na 0, zielony zestaw do FF która jest maksymalna wartość może mieć, a następnie czerwony zmienna ustawiona na 0, co wtedy kolor będzie ten konkretny RGB potrójny reprezentuje? >> [Uczeń] Green. Green. Dokładnie. To będzie przydatne wiedzieć, że gdy masz instancję RGB potrójne, rzeczywiście można przejść ilość kolorów - niebieski, zielony i czerwony - oddzielnie. Teraz, że rozmawialiśmy o strukturze, że rzućmy okiem na plik BMP. Są kodowanym dla Ciebie. Tutaj mamy struct BITMAPFILEHEADER. Interesująca jest rozmiar. Później mamy informację nagłówka, który ma jeszcze kilka rzeczy, które są interesujące dla nas, czyli wielkość, szerokości i wysokości. Jak pójdziemy na później, kiedy czytasz w do pliku, automatycznie odczytuje bo mamy ustawić kolejność jest taka sama. Więc biSize będzie zawierać odpowiednie bajty odpowiadające rzeczywistej wielkości obrazu. I to tutaj, na koniec, jak rozmawialiśmy o, mamy RGBTRIPLE typedef struct. Mamy rgbtBlue, zielony i czerwony z nim związane. Great. Okay. Teraz, kiedy rozumiemy bitmap trochę, zrozumieć, że mamy nagłówek pliku i nagłówek informacji związanych z nim, a następnie po tym, mamy ciekawe rzeczy z kolorów, a te kolory są reprezentowane przez RGBTRIPLE elemencie, a te z kolei są trzy wartości związane z niebieskie, zielone i czerwone. Więc teraz możemy trochę myślę o Przypomnij trochę. Przepraszam. Pomyśl o kryminał. Gdy mamy nasz plik wskazówkę, a potem to, co chcemy zrobić, to czytać w jej piksel po pikselu a potem jakoś zmienić te piksele tak, że możemy wyprowadzić go w czytelnej formie. I tak do wyprowadzania go, mamy zamiar napisać piksel po pikselu do verdict.bmp pliku. To trochę dużo do zrobienia. Zdajemy sobie sprawę, że. Więc, co zrobiliśmy to my faktycznie ci z copy.c. Co copy.c nie tylko tworzy dokładną kopię danego pliku mapy bitowej, a następnie wysyła go. Więc to już otwiera plik dla Ciebie, czyta w piksel po pikselu, a następnie zapisuje go do pliku wyjściowego. Rzućmy okiem na to. To jest zapewnienie właściwego użytkowania, uzyskanie nazw tutaj. Co to znaczy, że plik wejściowy ustawia się co my przekazany w INFILE tutaj który jest nasz drugi argument wiersza poleceń. Sprawdza się upewnić, że możemy otworzyć plik. Sprawdza, czy możemy zrobić nowy outfile tutaj. To co robi to tutaj, to po prostu w zasadzie zaczyna czytać w do plików graficznych od początku. Początki, jak wiadomo, zawiera BITMAPFILEHEADER, i tak te sekwencje bitów będzie bezpośrednio wypełnić BITMAPFILEHEADER. Więc co mamy tutaj jest powiedzenie, że BITMAPFILEHEADER BF - To nasza nowa zmienna BITMAPFILEHEADER typu - mamy zamiar umieścić wewnątrz bf, co czytamy w od wskaźnika, który jest naszym plik_we. Jak dużo czytamy? Czytamy w ile bajtów musimy zawierać cały BITMAPFILEHEADER. Podobnie, to co możemy zrobić w nagłówku info. Więc jesteśmy nadal wzdłuż naszego pliku w INFILE, i czytasz te bity i bajty, a my podłączając je bezpośrednio w do tych wystąpień zmiennych czyni, że jesteśmy. Tu po prostu upewnić się, że bitmapa jest bitmap. Teraz mamy outfile, prawda? Tak, to oznacza, gdy go utworzyć, jest zasadniczo puste. Musimy więc w zasadzie stworzyć nową bitmapę od podstaw. Co możemy zrobić, to musimy się upewnić, że możemy skopiować w nagłówku pliku i nagłówek informacji podobnie jak INFILE ma. Co możemy zrobić, to możemy napisać - i pamiętaj, że bf jest zmienna z BITMAPFILEHEADER typu, więc to, co możemy zrobić, to po prostu użyć tej treści napisać do outfile. Tutaj należy pamiętać, rozmawialiśmy o obicia, jak ważne jest, aby upewnić się, że ilość pikseli, które mamy jest wielokrotnością 4. Jest to całkiem przydatne wzór do obliczenia, ile masz wyściółka podana szerokość pliku. Chcę wam przypomnieć, że w copy.c mamy formułę obliczania dopełnienie. Okay? Więc wszyscy pamiętać. Great. Więc co robi następny copy.c jest to iteruje wszystkie scanlines. Przechodzi przez wiersze, a potem zapisuje każdy potrójny, że czyta , a następnie zapisuje się plik wyjściowy. Więc tutaj mamy tylko jedno czytanie RGB Triple w czasie a następnie wprowadzenie tego samego Triple do outfile. Najtrudniejsze jest to, że nie jest to dopełnienie RGB potrójne, i tak nie możemy przeczytać, że ilość dopełnienia trójek RGB. Co mamy zrobić, to faktycznie tylko przenieść nasz wskaźnik pozycji pliku, przenieść nasz kursor, do rodzaju przejść nad całą wyściółkę tak, że jesteśmy w następnym wierszu. I co wtedy robi to jest kopia pokazuje jak można dodać dopełnienie. Więc mamy obliczyć ile wyściółka musimy, więc to oznacza, że ​​musimy wiele wypychanie 0s. Co to znaczy dla pętli, który stawia szereg wypychanie 0s do naszego outfile. I wreszcie, można zamknąć oba pliki. Zamknięciu INFILE jak również OUTFILE. Więc tak copy.c prace, i że będzie to całkiem użyteczne. Zamiast faktycznie bezpośrednio skopiowanie i wklejenie lub po prostu patrząc na to i wpisując, co chcesz, może po prostu chcesz wykonać to polecenie w terminalu, cp copy.c whodunit.c, która stworzy nowy plik whodunit.c, , który zawiera dokładnie taką samą treść jak kopiowania. Tak więc, co możemy zrobić, to użyć tego jako ramy, na której można budować i edytować dla naszego pliku kryminalną. Są to nasze do-dos zrobić na kryminał, ale to co robi copy.c faktycznie dba o większość z nich dla nas. Więc wszystko, co musimy zrobić, to zmienić rozdzielczość, ile potrzeba aby rzeczywiście zrobić plik czytelny. Należy pamiętać, że dla danego piksela potrójnej, więc dla danego typu RGBTRIPLE zmiennej, można uzyskać dostęp do niebieski, zielony, czerwony i wartości. Że zamierza się przyda, bo jeśli można z nich korzystać, to oznacza, że ​​można również sprawdzić ich a to oznacza, że ​​można również zmienić. Więc kiedy wróciliśmy do naszego czerwonego np. lupy, zasadzie, że działał jako swego rodzaju filtr dla nas. Więc to, co chcemy zrobić, to chcemy, aby filtrować wszystkie trójek, które nadchodzą w. Istnieje kilka różnych sposobów, aby to zrobić. Zasadniczo, można mieć, niezależnie od typu filtru chcesz. Może chcesz zmienić wszystkie czerwone piksele a może chcesz zmienić inny piksel koloru na inny kolor. To zależy od Ciebie. Pamiętaj, że możesz sprawdzić, jaki kolor piksela jest a następnie można również zmienić go jak przechodzisz. Okay. Więc to Whodunit. Po uruchomieniu kryminał, będziesz wiedzieć, kto sprawcą zbrodni był. Teraz mamy zamiar iść do zmiany rozmiaru. Będziemy nadal mieć do czynienia z bitmapami. Co mamy zamiar zrobić, to będziemy mieć bitmapę wejściowego a następnie będziemy przechodzić w szeregu, a następnie uzyskać OUTFILE bitmapy gdzie to jest w zasadzie nasza plik_we skalowane przez n. Powiedz mój plik był tylko jeden piksel duże. Następnie, jeśli n to 3, skalowanie przez 3, to chciałbym powtórzyć, że piksel n ilość razy, tak 3 razy, a następnie również skalować go 3 razy, jak również. Więc widzisz, że skalowanie w pionie jak iw poziomie. I to tu jest przykład. Jeśli n = 2, widać, że pierwszy niebieski pixel nie powtarza się dwa razy poziomo, jak i dwa razy w pionie. A potem, że wciąż dalej, i tak masz bezpośredni skalowanie oryginalnego obrazu przez dwa. Więc gdybyśmy szczegółowo Pseudokod za to, że chcemy otworzyć plik. A potem, wiedząc, że jeśli wrócimy tutaj, widzimy, że szerokość w outfile będzie inna niż szerokość na INFILE. Co to znaczy? To oznacza, że ​​nasz nagłówek ulegnie zmianie. A więc to, co my chcemy zrobić to zaktualizować informacje nagłówka, wiedząc, że gdy czytamy w aktach, jeśli działa na copy.c ramach mamy już zmienną wskazującą na rozmiar jest i takie rzeczy. Więc kiedy już to, co możesz zrobić, to zmienić te poszczególne zmienne. Pamiętaj, że jeśli masz struct, jak uzyskać dostęp do zmiennych w tym. Możesz użyć operatora kropki, prawda? Tak więc przy użyciu tego, wiesz, że będziesz musiał zmienić informacje nagłówka. Tak tu jest tylko lista samych elementów, które będą się zmieniać w pliku. Rozmiar pliku będzie się zmieniać, obraz, jak również szerokość i wysokość. Więc wracając do mapy z map bitowych patrzeć czy to nagłówek pliku lub nagłówka informacji, który zawiera takie informacje , a następnie w razie potrzeby zmiany. Znowu, powiedzmy cp copy.c resize.c. To oznacza, że ​​teraz resize.c zawiera wszystko, co jest zawarte wewnątrz kopii ponieważ kopia daje nam sposób na czytanie w każdej linii skanowania piksel po pikselu. Lecz teraz, a nie tylko zmianę wartości tak jak my w kryminał, co chcemy zrobić, to chcemy zapisywać w kilku pikseli ile nasz n jest większe niż 1. Wtedy to, co chcemy zrobić, to chcemy rozciągnąć poziomo przez n, a także rozciągają się pionowo przez n. W jaki sposób możemy to zrobić? Wypowiedz n oznacza 2, a masz ten podany INFILE. Kursor ma się rozpocząć w pierwszej, i co chcesz zrobić, gdy n oznacza 2, aby wydrukować w 2 z nich. Więc drukować w 2 z nich. Następnie kursor będzie przejść do kolejnego piksela, która jest czerwona, i to będzie wydrukować 2 z tych czerwonych, dodając ją na to, co się stało wcześniej. Następnie kursor przesunie się do następnego piksela i zwrócić w 2 z nich. Jeśli spojrzeć wstecz na copy.c ram, co to robi tutaj jest to tworzy nową instancję RGB Trzyosobowy, nową zmienną o nazwie trzyosobowych. I tutaj, gdy wczytuje do niego, odczytuje z plik_we 1 RGBTRIPLE i zapisuje go w środku tej potrójnej zmiennej. Więc faktycznie masz zmienną reprezentującą ten konkretny piksel. Potem, kiedy piszesz, co możesz zrobić, to wstawcie do fwrite oświadczenie w pętli for który zapisuje go do outfile tyle razy, ile potrzeba. To jest dość proste. Wystarczy w zasadzie powtórzenie procesu pisania n liczbę razy go skalować poziomo. Ale wtedy musimy pamiętać, że nasze dopełnienie się zmieni. Wcześniej mieliśmy coś powiedzieć o długości 3. Wtedy po prostu dodać w ile dopełnienie? Jeszcze tylko jedno, aby to wielokrotność 4. Ale powiedzieć, że jesteśmy skalowania tego konkretnego obrazu przez n = 2. Więc ile niebieski pikseli mielibyśmy na końcu? Mielibyśmy 6. 1, 2, 3, 4, 5, 6. Dobrze. 6 nie jest wielokrotnością 4. Co znajduje się najbliższa wielokrotność 4? Że będzie to 8. Więc jesteśmy naprawdę będziemy mieć 2 znaki wyściółką tam. Czy ktoś pamięta, jeśli mamy na wyliczenie dopełnienia i gdzie to może być? [Niesłyszalne reakcja studentów] >> Tak, copy.c. Racja. Istnieje formuła w copy.c obliczyć, ile masz wyściółka przy określonym szerokość bitmapy. Tak więc, że będzie to przydatne, gdy trzeba dodać w pewnym wyściółką rzeczywiście dowiedzieć się, ile wyściółka trzeba dodać. Ale jedna uwaga, jest jednak to, że chcesz, aby upewnić się, że używasz odpowiedniego rozmiaru. Tylko uważaj, bo jesteś po prostu będzie do czynienia z dwoma bitmapy. Chcesz, aby upewnić się, że używasz właściwego. Kiedy obliczania dopełnienie dla outfile, chcesz używać szerokość outfile i nie szerokości poprzedniego. Great. Tego rodzaju zajmuje rozciąganie całego obrazu bitmapy w poziomie. Ale to, co chcemy zrobić, jest faktycznie rozciągnąć go w pionie, jak również. To będzie trochę trudniejsze, bo gdy skończymy kopiowanie wiersz i pisania tego wiersza, nasz kursor będzie na końcu. Więc jeśli czytamy ponownie, to jest to po prostu się czytać do następnego wiersza. Więc to, co chcemy zrobić, to rodzaj znaleźć jakiś sposób na skopiowanie tych wierszy ponownie lub po prostu rodzaj biorąc ten wiersz, a następnie przepisanie go ponownie. Jak rodzaj wspomniał, istnieje kilka różnych sposobów, aby to zrobić. Co można zrobić, to jak idziesz przez i czytanie przez konkretnego scanline i zmieniając go w razie potrzeby, a następnie rodzaj sklepu wszystkich tych pikseli w tablicy. Potem na ciebie wiem, że trzeba wydrukować tę tablicę ponownie, i tak można po prostu użyć tej tablicy to zrobić. Innym sposobem na to jest można skopiować w dół o jeden wiersz, Rozumiem, że trzeba skopiować, że ponownie, więc rzeczywiście przesunąć kursor, i to będzie za pomocą fseek metody. Można przesunąć kursor z powrotem i powtórz proces kopiowania ponownie. Więc jeśli nasz numer skalowanie jest n, to ile razy trzeba by wrócić i przepisać linię? >> [Uczeń] n - 1. >> Tak, doskonały. n - 1. Zrobiliśmy to już raz, więc wtedy będziemy chcieli powtórzyć trwający proces tylną n - 1 ilość razy. Okay. Więc masz swoją funkcję zmiany rozmiaru. Teraz możemy dotrzeć do bardzo zabawnej strony, moja ulubiona PSET, który jest Recover. Zamiast bitmapy, tym razem mamy do czynienia z JPEG. Jesteśmy faktycznie nie otrzymał plik tylko z plików JPEG, mamy podane w zasadzie surowy format karty pamięci. I tak to zawiera trochę informacji i śmieci wartości na początku, , a następnie zaczyna się i ma kilka plików JPEG. Jednak pracujemy wręczył kartę gdzie zostały usunięte zdjęcia; zasadniczo, zapomnieliśmy, gdzie zdjęcia znajdują się w karcie. Tak więc naszym zadaniem w Recover jest przejście przez ten format karty i znaleźć te zdjęcia ponownie. Na szczęście, struktura plików JPEG i plik kart jest nieco pomocny. To z pewnością mogło być nieco trudniejsze, gdyby nie było w tym konkretnym formacie. Każdy plik JPEG faktycznie zaczyna się od dwóch możliwych sekwencji, wymienionych powyżej. Zasadniczo, gdy masz nowy plik w formacie JPEG, zaczyna się albo sekwencji ffd8 ffe0 lub drugi, ffd8 ffe1. Inną pomocną rzeczą jest wiedzieć, że pliki JPEG są przechowywane ciągły. Tak więc, gdy jeden plik JPEG kończy, drugi zaczyna. Więc nie każdy rodzaj w między wartościami jest. Po trafieniu początek JPEG, jeśli już zostały czytania w formacie JPEG, wiesz, że został trafiony koniec poprzedniego i na początku następnego. Do rodzaju wizualizacji tego, zrobiłem schemat. Inną rzeczą jest to, że JPEG możemy czytać je w sekwencji 512 bajtów na raz, Podobnie z początku karty. Nie trzeba sprawdzać każdy pojedynczy bajt bo to do dupy. Zamiast więc, co możemy zrobić, to właściwie tylko czytać w 512 bajtów na raz , a następnie, zamiast sprawdzania Pomiędzy tymi w tych małych drobnych plasterki, możemy po prostu sprawdzić na początek 512 bajtów. Zasadniczo, w obrazie, co widać w początku karty masz wartości, które nie są naprawdę istotne dla rzeczywistych JPEG samych. Ale to co mam jest gwiazda wskazać jedną z dwóch sekwencji wyjścia dla JPEG. Więc kiedy zobaczysz gwiazdę, wiesz, że masz plik JPEG. I wtedy każdy plik JPEG będzie niektóre wielokrotnością 512 bajtów ale niekoniecznie taką samą wielokrotność. Sposób, że wiesz, że został trafiony kolejny JPEG jeśli trafisz inną gwiazdę, drugim od sekwencji bajtów. Wtedy to, co masz o to masz czerwony plik JPEG ciągłą aż trafisz na gwiazdę, co wskazuje na nowy kolor. Nadal, a potem uderzył inną gwiazdę, trafiasz kolejny JPEG, można kontynuować aż do końca. Jesteś na ostatnim zdjęciu tutaj, różowy. Możesz przejść do końca, aż trafisz na znak końca pliku. To będzie naprawdę przydatne. Kilka głównych takeaways tutaj: Kartoteka nie zaczyna się w formacie JPEG, ale po JPEG uruchomieniu wszystkie JPEG są przechowywane obok siebie. Niektóre Pseudokod dla Recover. Po pierwsze, mamy zamiar otworzyć nasz plik karty, i to będzie za pomocą nasz plik I / O funkcji. Będziemy powtarzać następujący proces, dopóki nie dotarł do końca pliku. Będziemy czytać 512 bajtów na raz. I to, co powiedziałem o to będziemy go przechowywać w buforze, więc w zasadzie trzymać się tych 512 bajtów dopóki nie wiemy dokładnie, co z nimi zrobić. Wtedy to, co chcemy zrobić, to chcemy, aby sprawdzić, czy mamy uderzyć gwiazdę lub nie. Jeśli mamy hit gwiazdy, jeśli został trafiony jedną z sekwencji wyjściowych, to wiemy, że mamy hit nowy plik JPEG. Co będziemy chcieli zrobić, to mamy zamiar utworzyć nowy plik w katalogu naszego pset4 o dokonywaniu tego pliku. Ale również, jeśli mamy już wykonane w formacie JPEG przed, to chcemy zakończyć ten plik i wciśnij go do pset4 folderze gdzie będziemy mieli, że plik zapisany, ponieważ jeśli nie określić, że mamy zakończony, że plik JPEG, wtedy będziemy w zasadzie mają nieokreśloną kwotę. W JPEG nigdy nie skończy. Dlatego chcemy, aby upewnić się, że gdy czytasz w do pliku JPEG i piśmie, chcemy specjalnie blisko, że aby otworzyć następny. Chcemy się sprawdzić kilka rzeczy. Chcemy sprawdzić, czy jesteśmy na początku nowego JPEG z naszym buforze a także jeśli już znalazłem JPEG przed dlatego, że zmieni swój proces lekko. Tak więc po przejściu przez całą drogę, a trafisz na koniec pliku, to co będziesz chciał zrobić, to będziemy chcieli, aby zamknąć wszystkie pliki, które są obecnie otwarte. To będzie prawdopodobnie ostatni plik JPEG, że masz, jak kartoteki, że już do czynienia. Ostatnią przeszkodą, że musimy rozwiązać to jak rzeczywiście zrobić plik JPEG i jak rzeczywiście przesunąć go do folderu. Pset wymaga, aby każdy JPEG, które można znaleźć w następującym formacie gdzie masz numer. jpg. Numer, nawet jeśli jest to 0, nazywamy to 000.jpg. Gdy znajdziesz w formacie JPEG w programie, będziesz chciał wymienić je w kolejności, w jakiej się znalazł. Co to znaczy? Musimy rodzaju śledzić ile odkryliśmy i co liczba powinna być każdego JPEG. Tutaj mamy zamiar skorzystać z funkcji sprintf. Podobna do printf, które po prostu rodzaj wydruków wartość obecnie w terminalu, sprintf drukuje plik się do folderu. A więc co by to zrobić, gdybym miał sprintf, tytuł, a następnie ciąg tam, byłoby wydrukować 2.jpg. Zakładając, że mam zamknięte moje pliki poprawnie, które zawiera plik, który był w tym piśmie się. Ale jedna rzecz jest to, że kod, który mam tutaj nie dość spełniają co pset wymaga. Pset wymaga sekund plików JPEG powinny być nazwane 002 zamiast tylko 2. Więc kiedy wydrukować nazwę, to może warto zmienić zastępczy lekko. Czy ktoś pamięta, jak pozwalają na dodatkowych spacji, gdy drukujemy coś? Tak. >> [Uczeń] Możesz umieścić 3 między znakiem procentu i 2. >> Tak, doskonały. Będziesz umieścić 3 w tym przypadku, ponieważ chcemy miejsca dla 3. % 3d prawdopodobnie dać 002.jpg zamiast 2. Pierwszy argument do funkcji sprintf jest rzeczywiście tablica char, których wcześniej znał jako łańcuchy. Będą, rodzaj bardziej jak składowania czasowego, po prostu zapisać wynikowy ciąg. Ty naprawdę nie będą mieć do czynienia z tym, ale trzeba go zawierać. Wiedząc, że każda nazwa pliku ma numer, który odbywa się trzy znaki, i wtedy. jpg, jak długo należy ta tablica będzie? Wyrzuć numer. Ile znaków w tytule, w imię? Więc jest 3 hashtags, okres, JPG. >> [Uczeń] 7. >> 7. Nie całkiem. Będziemy chcieli 8, ponieważ chcemy, aby umożliwić terminator null również. Wreszcie, po prostu wyciągnąć proces, będziesz robił za odzyskiwanie, masz jakąś informacje początkowy. Nadal, aż znajdziesz początek pliku JPEG, oraz, że może być jednym z dwóch sekwencji wyjściowych. Można przechowywać na czytanie. Każdy slash tutaj reprezentuje 512 bajtów. Można przechowywać na czytaniu, aby zapoznawali aż znowu pojawi sekwencję początkową. Kiedy już, że w końcu bieżącego JPEG - w tym przypadku, to jest czerwony, tak chcesz zakończyć to. Chcesz sprintf nazwy że w swojej pset4 folderze to chcesz otworzyć nowy JPEG, a następnie kontynuować czytanie aż pojawią się następne. Zachowaj na czytaniu, przechowywać na czytanie, i wreszcie, w końcu masz zamiar dotrzeć do końca pliku, i tak będziesz chciał, aby zamknąć ostatnią JPEG, które zostały z pracy, sprintf, że do swojego pset4 folderu, a następnie spójrz na wszystkie zdjęcia, które dostaliśmy. Te zdjęcia są faktycznie zdjęcia CS50 personelu, i tak to jest, gdy część zabawy premia z Pset przychodzi jest to, że są konkurencyjne w swoich sekcjach znaleźć TFS na zdjęciach i zdjęcia z nimi, aby udowodnić, że zrobiłeś z Pset i tak można zobaczyć, które pracownicy są na zdjęciach. Tak więc wykonywanie zdjęć z personelem. Czasami będziesz musiał gonić ich. Prawdopodobnie część z nich będzie starał się uciec od ciebie. Robić zdjęcia z nimi. To jest w toku. To nie z powodu, gdy zbior jest należny. Termin zostanie ogłoszony w spec. Następnie wraz z sekcji, w zależności od sekcji zajmuje najwięcej zdjęć z największą liczbą pracowników wygra dość niesamowite nagrody. To rodzaj zachęty, aby uzyskać pset4 zakończone tak szybko, jak to możliwe bo wtedy można zabrać się do pracy polowanie na wszystkich różnych CS50 pracowników. To nie jest obowiązkowe, choć, więc gdy się zdjęcia, wtedy są wykończone pset4. I jestem wykończony Walkthrough 4, więc dziękuję wszystkim za przybycie. Powodzenia z Forensics. [Oklaski] [CS50.TV]