JavaRush /Blog Java /Random-MS /Harvard CS50: Tugasan Minggu 4 (Kuliah 9 dan 10)
Masha
Tahap

Harvard CS50: Tugasan Minggu 4 (Kuliah 9 dan 10)

Diterbitkan dalam kumpulan
Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 1

Bersedia untuk bekerja

Seperti biasa, mula-mula buka tetingkap terminal dan jalankan arahan. update50 untuk memastikan permohonan anda sudah dikemas kini. Sebelum anda memulakan, ikuti ini cd ~ / workspace wget http://cdn.cs50.net/2015/fall/psets/4/pset4/pset4.zip untuk memuat turun arkib ZIP tugas ini. Sekarang jika anda menjalankan ls anda akan melihat bahawa anda mempunyai fail yang dipanggil pset4.zip dalam direktori ~/workspace anda . Ekstraknya menggunakan arahan: Jika anda menjalankan unzip pset4.zip perintah ls sekali lagi , anda akan melihat bahawa direktori lain telah muncul. Kini anda boleh memadam fail zip seperti yang ditunjukkan di bawah: rm -f pset4.zip Mari buka direktori pset4 cd pset4 , jalankan ls , dan pastikan direktori tersebut mengandungi bmp / jpg / questions.txt

whodunit atau "Siapa yang melakukan ini?"

Jika anda pernah melihat desktop Windows XP lalai (https://en.wikipedia.org/wiki/Bliss_(image)) (bukit dan langit biru), maka anda telah melihat BMP. Pada halaman web, kemungkinan besar anda telah melihat GIF. Pernahkah anda melihat foto digital? Jadi, kami gembira melihat JPEG. Jika anda pernah mengambil tangkapan skrin pada Mac, kemungkinan besar anda telah melihat PNG. Baca di Internet tentang format BMP, GIF, JPEG, PNG dan jawab soalan ini:
  1. Berapa banyak warna yang setiap format menyokong?

  2. Format mana yang menyokong animasi?

  3. Apakah perbezaan antara pemampatan lossy dan lossless?

  4. Manakah antara format ini menggunakan pemampatan lossy?

Mereka yang berbahasa Inggeris dinasihatkan untuk merujuk artikel dari MIT . Jika anda mengkajinya (atau mencari sumber lain di Internet tentang menyimpan fail pada cakera dan sistem fail), anda boleh menjawab soalan berikut:
  1. Apakah yang berlaku dari sudut teknikal apabila fail dipadamkan dalam sistem fail FAT?

  2. Apakah yang boleh dilakukan untuk memastikan (dengan kebarangkalian yang tinggi) bahawa fail yang dipadam tidak dapat dipulihkan?

Dan sekarang - untuk kisah kami, yang lancar mengalir ke tugas pertama minggu keempat. Selamat datang ke Tudor Mansion! Pemilik ladang, Encik John Boddy, tiba-tiba meninggalkan kami, menjadi mangsa permainan yang tidak jelas. Untuk mengetahui apa yang berlaku, anda mesti mentakrifkan whodunit . Malangnya untuk anda (walaupun lebih malang lagi untuk En. Boddy), satu-satunya bukti yang anda ada ialah petunjuk fail BMP 24-bit.bmp . Ia adalah kandungannya yang anda lihat di bawah. En. Boddy berjaya membuat dan menyimpannya pada komputernya pada saat-saat terakhirnya. Fail itu mengandungi imej whodunit yang tersembunyi di antara bunyi merah . Kini anda perlu mengusahakan penyelesaian seperti pakar teknikal sebenar. Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 2Tetapi pertama, beberapa maklumat. Ia mungkin paling mudah untuk memikirkan imej sebagai grid piksel (titik, iaitu), yang setiap satunya boleh menjadi warna tertentu. Untuk menetapkan warna titik dalam imej hitam dan putih, kita memerlukan 1 bit. 0 boleh mewakili hitam dan 1 boleh mewakili putih seperti yang ditunjukkan dalam gambar di bawah. Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 3Oleh itu, imej yang diwakili dengan cara ini hanyalah peta bit (peta bit atau peta bit, seperti yang mereka katakan dalam bahasa Inggeris atau slanga). Dengan hitam dan putih semuanya semudah mungkin, tetapi untuk mendapatkan imej berwarna kita hanya memerlukan lebih banyak bit setiap piksel. Format fail (seperti GIF) yang menyokong "warna 8-bit" menggunakan 8 bit setiap piksel. Format fail (cth., BMP, JPG, PNG) yang menyokong "warna 24-bit" menggunakan 24 bit setiap piksel (BMP sebenarnya menyokong warna 1-, 4-, 8-, 16-, 24- dan 32-bit) . Dalam BMP 24-bit yang En. Boddy gunakan, diperlukan 8 bit untuk menunjukkan jumlah merah, jumlah yang sama untuk hijau, dan sekali lagi 8 bit untuk menunjukkan jumlah biru dalam setiap piksel. Jika anda pernah mendengar tentang warna RGB , ini dia (R=merah, G=hijau, B=biru). Jika nilai R, G dan B bagi sesetengah piksel dalam BMP ialah, katakan, 0xff, 0x00 dan 0x00 dalam perenambelasan, maka piksel itu akan menjadi merah tulen, kerana 0xff (atau dikenali sebagai 255 dalam perpuluhan) bermaksud "banyak merah " pada masa itu sebagai 0x00 dan 0x00 masing-masing bermaksud "tiada hijau" dan "biru juga sifar". Memandangkan bagaimana imej BMP Encik Boddy merah kelihatan kepada kami, adalah intuitif bahawa "petak" merah mempunyai nilai yang jelas lebih besar daripada "petak" merah dan biru. Walau bagaimanapun, tidak semua piksel berwarna merah; sesetengahnya jelas dengan warna yang berbeza. Ngomong-ngomong, dalam HTML dan CSS (bahasa penanda dan helaian gaya yang membantunya, yang digunakan untuk membuat halaman web), model warna disusun dengan cara yang sama. Jika berminat, lihat pautan: https://ru.wikipedia.org/wiki/Colors_HTMLuntuk maklumat lanjut. Sekarang mari kita mendekati masalah secara lebih teknikal. Ingat bahawa fail hanyalah satu jujukan bit yang disusun dalam beberapa susunan. Fail BMP 24-bit ialah jujukan bit, setiap 24 daripadanya (baik, hampir) menentukan warna piksel mana. Selain data warna, fail BMP juga mengandungi metadata - maklumat tentang lebar dan ketinggian imej. Metadata ini disimpan pada permulaan fail dalam bentuk dua struktur data yang biasa dipanggil "pengepala" (jangan dikelirukan dengan fail pengepala C). Pengepala pertama ini ialah BITMAPFILEHEADER, iaitu 14 bait panjang (atau 14*8 bit). Pengepala kedua ialah BITMAPINFOHEADER (40 bait panjang). Selepas pengepala ini datang peta bit: tatasusunan bait, tiga kali ganda daripadanya mewakili warna piksel (1, 4 dan 16-bit dalam BMP, tetapi bukan 24 atau 32, mereka mempunyai pengepala tambahan sejurus selepas BITMAPINFOHEADER. Ia dipanggil tatasusunan RGBQUAD, mentakrifkan "nilai keamatan" untuk setiap warna dalam palet). Walau bagaimanapun, BMP menyimpan kembar tiga ini secara terbalik (kita boleh katakan seperti BGR), dengan 8 bit untuk biru, 8 bit untuk hijau dan 8 bit untuk merah. Ngomong-ngomong, sesetengah BMP juga menyimpan keseluruhan bitmap ke belakang, bermula dari baris atas imej pada penghujung fail BMP. Dalam tugas kami, kami menyimpan VMR seperti yang diterangkan di sini, pertama baris atas imej, kemudian baris bawah. Dalam erti kata lain, kami menukar emoji satu-bit kepada 24-bit dengan menggantikan hitam dengan merah. BMP 24-bit akan menyimpan peta bit ini, di mana 0000ff mewakili merah dan ffffff mewakili putih; kami telah menyerlahkan semua kejadian 0000ff dalam warna merah. Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 4Memandangkan kami membentangkan bit ini dari kiri ke kanan, atas ke bawah, anda boleh melihat wajah tersenyum merah dalam huruf ini jika anda bergerak sedikit dari monitor. Ingat bahawa satu digit dalam sistem nombor heksadesimal mewakili 4 bit. Sehubungan itu, ffffff dalam perenambelasan sebenarnya bermaksud 11111111111111111111111111 dalam binari. Sekarang, perlahan dan jangan pergi lebih jauh sehingga anda pasti anda faham mengapa 0000ff mewakili piksel merah dalam fail BMP 24-bit. Dalam tetingkap CS50 IDE, kembangkan (contohnya, dengan mengklik pada segitiga kecil) folder pset4 , dan di dalamnya - bmp . Dalam folder ini anda akan menemui smiley.bmp , klik dua kali pada fail dan anda akan menemui smiley kecil 8x8 piksel di sana. Dalam menu lungsur, tukar skala imej, katakan daripada 100% kepada 400%, ini akan membolehkan anda melihat versi emotikon yang lebih besar, tetapi pada masa yang sama lebih "kabur". Walaupun pada hakikatnya imej yang sama ini tidak boleh dikaburkan walaupun dibesarkan. Cuma CS50 IDE cuba membantu anda (dalam gaya siri CIA) dengan melicinkan gambar (mengkaburkan tepi secara visual). Beginilah rupa senyuman kita jika kita membesarkannya tanpa melicinkan: Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 5Piksel bertukar menjadi segi empat sama besar. Jom sambung. Di terminal pergi ke ~/workspace/pset4/bmp . Kami fikir anda sudah ingat bagaimana untuk melakukan ini. Mari kita periksa bait yang diperuntukkan dalam smiley.bmp . Ini boleh dilakukan menggunakan editor hex baris arahan, program xxd . Untuk menjalankannya, jalankan arahan: xxd -c 24 -g 3 -s 54 smiley.bmp Anda harus melihat apa yang ditunjukkan di bawah; Kami telah menyerlahkan lagi dengan warna merah semua contoh 0000ff. Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 6Dalam imej dalam lajur paling kiri anda boleh melihat alamat dalam fail, yang bersamaan dengan offset daripada bait pertama fail. Kesemuanya diberikan dalam sistem nombor heksadesimal. Jika kita menukar perenambelasan 00000036 kepada perpuluhan, kita mendapat 54. Jadi anda sedang melihat bait ke-54 daripada smiley.bmp . Ingat bahawa dalam fail BMP 24-bit, 14 + 40 = 54 bait pertama diisi dengan metadata. Jadi, jika anda ingin melihat metadata, jalankan arahan berikut: xxd -c 24 -g 3 smiley.bmp Jika smiley.bmp mengandungi aksara ASCII , kami akan melihatnya di lajur paling kanan dalam xxd dan bukannya semua titik tersebut. Jadi, smiley ialah BMP 24-bit (setiap piksel diwakili oleh 24 ÷ 8 = 3 bait) dengan saiz (resolusi) 8x8 piksel. Oleh itu, setiap baris (atau "Scanline" dipanggil) mengambil (8 piksel) x (3 bait setiap piksel) = 24 bait. Nombor ini ialah gandaan empat, dan ini penting kerana fail BMP disimpan sedikit berbeza jika bilangan bait dalam baris bukan gandaan empat. Jadi, dalam small.bmp, satu lagi fail BMP 24-bit dalam folder kami, anda boleh melihat kotak hijau 3x3 piksel. Jika anda membukanya dalam pemapar imej, anda akan melihat bahawa ia menyerupai imej yang ditunjukkan di bawah, hanya bersaiz lebih kecil. Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 7Oleh itu, setiap baris dalam small.bmp menduduki (3 piksel) × (3 bait setiap piksel) = 9 bait, yang bukan gandaan 4. Untuk mendapatkan panjang baris yang gandaan 4, ia berlapik dengan sifar tambahan: antara 0 dan 3 bait kami mengisi setiap baris dalam format BMP 24-bit (bolehkah anda meneka mengapa demikian?). Untuk small.bmp , 3 bait sifar diperlukan, memandangkan (3 piksel) x (3 bait setiap piksel) + (3 bait padding) = 12 bait, yang sebenarnya merupakan gandaan 4. Untuk "melihat" padding ini, lakukan perkara berikut. xxd -c 12 -g 3 -s 54 small.bmp Ambil perhatian bahawa kami menggunakan nilai yang berbeza untuk -c berbanding dengan smiley.bmp , jadi xxd hanya mengeluarkan 4 lajur kali ini (3 untuk petak hijau dan 1 untuk padding). Untuk kejelasan, kami telah menyerlahkan semua kejadian 00ff00 dalam warna hijau. Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 8Sebagai kontras, mari gunakan xxd untuk fail large.bmp . Ia kelihatan sama persis dengan small.bmp, hanya resolusinya ialah 12x12 piksel, iaitu empat kali lebih besar. Jalankan arahan di bawah. Anda mungkin perlu mengembangkan tetingkap untuk mengelakkan pemindahan. xxd -c 36 -g 3 -s 54 large.bmp Anda akan melihat sesuatu seperti ini: Harvard CS50: Tugasan Minggu 4 (Kuliah 9 dan 10) - 9Sila ambil perhatian, tiada penyelewengan dalam BMP ini! Lagipun, (12 piksel) × (3 bait setiap piksel) = 36 bait, dan ini adalah gandaan 4. Editor hex xxd menunjukkan kepada kami bait dalam fail BMP kami. Bagaimanakah kita boleh mendapatkannya secara pemrograman? Dalam copy.c terdapat satu program yang tujuan utamanya dalam hidup adalah untuk mencipta salinan BMP, sekeping demi sekeping. Ya, anda boleh menggunakan cp untuk ini . Walau bagaimanapun, cp tidak akan dapat membantu En Boddy. Harap copy.c melakukan ini, jadi begini: ./copy smiley.bmp copy.bmp Jika anda sekarang menjalankan ls (dengan bendera yang sesuai), anda akan melihat smiley.bmp dan copy.bmp sememangnya mempunyai saiz yang sama. Mari kita semak semula sama ada ini benar? diff smiley.bmp copy.bmp Jika arahan ini tidak memaparkan apa-apa pada skrin, ini bermakna fail itu sememangnya sama (penting: sesetengah program, seperti Photoshop, menyertakan sifar tertinggal di hujung beberapa VMP. Versi salinan kami membuangnya, jadi jangan bimbang jika sekiranya anda menyalin BMP lain yang telah anda muat turun atau cipta untuk ujian, salinan itu akan menjadi beberapa bait lebih kecil daripada yang asal). Anda boleh membuka kedua-dua fail dalam pemapar imej Ristretto (klik dua kali) untuk mengesahkan ini secara visual. Tetapi diff melakukan perbandingan bait demi bait ini, jadi penglihatannya lebih tajam daripada anda! Bagaimanakah salinan ini dicipta? Ternyata copy.c berkaitan dengan bmp.h . Mari pastikan: buka bmp.h. Di sana anda akan melihat takrifan sebenar pengepala yang telah kami nyatakan, disesuaikan daripada pelaksanaan Microsoft sendiri. Selain itu, fail ini mentakrifkan jenis data BYTE, DWORD, LONG dan WORD, yang merupakan jenis data yang biasanya ditemui dalam dunia pengaturcaraan Win32 (iaitu, Windows). Ambil perhatian bahawa ini pada dasarnya adalah alias untuk primitif yang anda (semoga) sudah biasa dengannya. Ternyata BITMAPFILEHEADER dan BITMAPINFOHEADER telah menggunakan jenis ini. Fail ini juga mentakrifkan struct yang dipanggil RGBTRIPLE. Ia "merangkum" tiga bait: satu biru, satu hijau dan satu merah (ini adalah susunan di mana kita akan mencari kembar tiga RGB pada cakera). Bagaimanakah struct ini berguna? Untuk meringkaskan, fail hanyalah jujukan bait (atau akhirnya bit) pada cakera. Walau bagaimanapun, bait ini biasanya dipesan supaya beberapa yang pertama mewakili sesuatu, kemudian yang berikutnya mewakili sesuatu yang lain, dan seterusnya. "Format" fail wujud kerana kami mempunyai piawaian, atau peraturan, yang mentakrifkan maksud bait. Sekarang, kita hanya boleh membaca fail dari cakera ke dalam RAM sebagai satu tatasusunan bait besar. Dan kita ingat bahawa bait pada kedudukan [i] mewakili satu perkara, manakala bait pada kedudukan [j] adalah sesuatu yang lain. Tetapi mengapa tidak berikan beberapa nama bait ini supaya kita boleh mendapatkannya dengan lebih mudah daripada ingatan? Ini adalah apa yang struktur dalam bmp.h membantu kami. Daripada memikirkan fail sebagai satu jujukan bait yang panjang, kami melihatnya dipecahkan kepada blok yang lebih mudah difahami - jujukan struktur. Ingat bahawa smiley.bmp mempunyai resolusi 8x8 piksel, jadi ia memerlukan 14 + 40 + (8 × 8) × 3 = 246 bait pada cakera (anda boleh menyemak ini menggunakan arahan ls). Begini rupanya pada cakera menurut Microsoft: Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 10Kami dapat melihat bahawa pesanan itu penting apabila ia melibatkan ahli struct. Byte 57 ialah rgbtBlue (bukan, katakan, rgbtRed) kerana rgbtBlue ditakrifkan dalam RGBTRIPLE dahulu. Ngomong-ngomong, penggunaan atribut padak kami memastikan bahawa dentang tidak cuba "menjajarkan perkataan" ahli (dengan alamat bait pertama setiap ahli ialah gandaan 4), supaya kami tidak berakhir dengan lubang dalam struktur kami yang tidak wujud pada cakera sama sekali. Jom teruskan. Cari URL yang sepadan dengan BITMAPFILEHEADER dan BITMAPINFOHEADER, mengikut ulasan dalam bmp.h. Perhatian, saat yang hebat: anda mula menggunakan MSDN (Rangkaian Pembangun Microsoft)! Daripada menatal lebih jauh melalui copy.c , jawab beberapa soalan untuk memahami cara kod tersebut berfungsi. Seperti biasa, arahan lelaki adalah kawan sejati anda, dan kini juga MSDN. Jika anda tidak tahu jawapannya, Google dan fikirkan. Anda juga boleh merujuk kepada fail stdio.h di https://reference.cs50.net/.
  1. Tetapkan titik putus dalam utama (dengan mengklik di sebelah kiri pembaris dengan nombor baris utama).

  2. Dalam tab terminal , pergi ke ~/workspace/pset4/bmp , dan susun copy.c ke dalam atur cara salin menggunakan make.

  3. Jalankan debug50 copy smiley.bmp copy.bmp , ini akan membuka panel debugger di sebelah kanan.

  4. Berjalan melalui program langkah demi langkah menggunakan panel di sebelah kanan. Nota bf dan bi . Dalam ~/workspace/pset4/questions.txt , jawab soalan:

  • Apakah stdint.h ?

  • Apakah gunanya menggunakan uint8_t , uint32_t , int32_t dan uint16_t dalam program?

  • Berapakah bilangan bait yang masing-masing mengandungi BYTE , DWORD , LONG dan WORD (Dengan mengandaikan seni bina 32-bit)?

  • Apakah (ASCII, perpuluhan atau perenambelasan) sepatutnya dua bait pertama fail BMP? (bait utama, yang digunakan untuk mengenal pasti format fail (dengan kebarangkalian tinggi) sering dipanggil "nombor ajaib").
  • Apakah perbezaan antara bfSize dan biSize?

  • Apakah maksud biHeight negatif?

  • Medan manakah dalam BITMAPINFOHEADER mentakrifkan kedalaman warna dalam BMP (iaitu bit setiap piksel)?

  • Mengapa fungsi fopen boleh mengembalikan NULL dalam copy.c 37?

  • Mengapa hujah ketiga untuk fread dalam kod kami sama dengan 1?

  • Apakah nilai dalam copy.c 70 mentakrifkan padding jika bi.biWidth ialah 3?

  • Apa yang fseek lakukan?

  • Apakah SEEK_CUR?

Kembali kepada Encik Boddy. Senaman:

Tulis program yang dipanggil whodunit dalam fail yang dipanggil whodunit.c yang menunjukkan lukisan Encik Boddy. Hmmmm, apa? Seperti salinan, program mesti mengambil tepat dua argumen baris arahan, dan jika anda menjalankan program anda seperti yang ditunjukkan di bawah, hasilnya akan disimpan dalam verdict.bmp, di mana lukisan En. Boddy tidak akan bising. ./whodunit clue.bmp verdict.b Biar kami cadangkan anda akan mula menyelesaikan misteri ini dengan menjalankan arahan di bawah. cp copy.c whodunit.c Anda mungkin kagum dengan berapa banyak baris kod yang anda perlu tulis untuk membantu En. Boddy. Tiada apa-apa yang tidak perlu disembunyikan dalam smiley.bmp , jadi jangan ragu untuk menguji atur cara pada fail ini. Ia kecil, dan anda boleh membandingkan output program anda dan output xxd semasa pembangunan (atau mungkin ada sesuatu yang tersembunyi dalam smiley.bmp ? Sebenarnya, tidak). Dengan cara ini, masalah ini boleh diselesaikan dengan cara yang berbeza. Sebaik sahaja anda mengenal pasti lukisan Encik Boddy, dia akan berehat dengan tenang. Memandangkan whodunit boleh dilaksanakan dalam pelbagai cara, anda tidak akan dapat menyemak ketepatan pelaksanaan dengan check50 . Dan biarkan ia merosakkan keseronokan anda, tetapi penyelesaian pembantu juga tidak tersedia untuk masalah whodunit . Akhir sekali, dalam fail Dalam ~/workspace/pset4/questions.txt , jawab soalan berikut: Whodunit? //ктоэтосделал?

ubah saiz

Nah, sekarang - ujian seterusnya! Mari kita tulis atur cara yang dipanggil resize in resize.c . Ia akan mengubah saiz imej BMP 24-bit yang tidak dimampatkan dalam langkah n. Aplikasi anda mesti menerima tepat tiga argumen baris arahan, dengan yang pertama (n) ialah integer tidak lebih daripada 100, yang kedua ialah nama fail yang akan diubah suai dan yang ketiga ialah nama versi yang disimpan bagi yang diubah suai fail. Usage: ./resize n infile outfile Dengan program sedemikian, kita boleh mencipta large.bmp daripada small.bmp dengan mengubah saiz yang terakhir dengan 4 (iaitu, mendarab kedua-dua lebar dan tinggi dengan 4), seperti yang ditunjukkan di bawah. Untuk memudahkan, anda boleh memulakan tugas dengan menyalin copy.c./resize 4 small.bmp large.bmp sekali lagi dan menamakan salinan resize.c . Tetapi pertama-tama, tanya diri anda dan jawab soalan-soalan ini: apakah maksud menukar saiz BMP (anda boleh mengandaikan bahawa n kali saiz fail tidak akan melebihi 232 - 1) . Tentukan medan dalam BITMAPFILEHEADER dan BITMAPINFOHEADER yang perlu anda ubah. Pertimbangkan sama ada anda perlu menambah atau mengalih keluar medan garis imbasan . Dan, ya, bersyukur kerana kami tidak meminta anda untuk mempertimbangkan semua kemungkinan nilai n dari 0 hingga 1! (walaupun, jika anda berminat, ini adalah masalah dari buku penggodam ;)). Walau bagaimanapun, kami menganggap bahawa untuk n = 1 atur cara akan berfungsi dengan betul dan fail keluar fail keluaran akan sama saiz dengan fail dalam asal. Adakah anda ingin menyemak program menggunakan check50? Taip arahan berikut: check50 2015.fall.pset4.resize bmp.h resize.c Adakah anda mahu bermain dengan pelaksanaan aplikasi yang dibuat oleh pembantu CS50? Jalankan yang berikut: ~cs50/pset4/resize Nah, jika anda ingin melihat, sebagai contoh, pengepala large.bmp (dalam bentuk yang lebih mesra pengguna daripada yang dibenarkan xxd), anda perlu menjalankan arahan berikut: ~cs50/pset4/peek large.bmp Lebih baik lagi, jika anda ingin membandingkan anda pengepala dengan pengepala fail pembantu CS50. Anda boleh menjalankan arahan di dalam direktori ~/workspace/pset4/bmp anda (fikirkan tentang apa yang dilakukan oleh setiap arahan). Jika anda menggunakan malloc , pastikan anda menggunakan percuma untuk mengelakkan kebocoran memori. Cuba gunakan valgrind untuk memeriksa kebocoran. ./resize 4 small.bmp student.bmp
~cs50/pset4/resize 4 small.bmp staff.bmp
~cs50/pset4/peek student.bmp staff.bmp

Bagaimana untuk membuat keputusan?

  • Buka fail yang perlu kita besarkan, dan juga buat dan buka fail baharu di mana imej yang diperbesarkan akan direkodkan;

  • kemas kini maklumat pengepala untuk fail output. Memandangkan imej kami dalam format BMP dan kami menukar saiznya, kami perlu menulis pengepala fail baharu dengan dimensi baharu. Apa yang akan berubah? Saiz fail, serta saiz imej - lebar dan ketinggiannya.

Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 11Jika kita melihat penerangan pengepala, kita akan melihat pembolehubah biSizeImage . Ia menunjukkan jumlah saiz imej dalam bait, biWidth ialah lebar imej tolak penjajaran, biHeight ialah ketinggian. Pembolehubah ini terletak dalam struktur BITMAPFILEHEADER dan BITMAPINFOHEADER. Anda boleh menemuinya jika anda membuka fail bmp.h . Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 12Perihalan struktur BITMAPINFOHEADER mengandungi senarai pembolehubah. Untuk menulis tajuk fail output, anda perlu menukar nilai ketinggian dan lebar. Tetapi terdapat juga kemungkinan bahawa kemudian anda memerlukan ketinggian dan lebar asal fail asal. Oleh itu, adalah lebih baik untuk menyimpan kedua-duanya. Berhati-hati dengan nama pembolehubah supaya anda tidak secara tidak sengaja menulis data yang salah dalam pengepala fail output.
  • Kami membaca fail keluar, baris demi baris, piksel demi piksel. Untuk melakukan ini, kami sekali lagi beralih ke perpustakaan I/O fail kami dan fungsi fread. Ia memerlukan penuding kepada struktur yang akan mengandungi bait yang dibaca, saiz elemen tunggal yang akan kita baca, bilangan elemen tersebut dan penunjuk kepada fail yang akan kita baca.

    Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 13
  • Kami meningkatkan setiap baris secara mendatar mengikut skala yang ditentukan, dan menulis hasilnya ke fail output.

    Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 14

    Bagaimana kita menulis fail? Kami mempunyai fungsi fwrite, yang mana kami menghantar penunjuk kepada struktur di mana data yang akan ditulis ke fail terletak, saiz elemen, nombor mereka dan penunjuk ke fail output. Untuk mengatur gelung, kita boleh menggunakan gelung for yang kita sudah biasa dengan .

    Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 15
  • Mengisi ruang! Jika bilangan piksel dalam baris bukan gandaan empat, kita mesti menambah "penjajaran" - bait sifar. Kami memerlukan formula untuk mengira saiz penjajaran. Untuk menulis bait nol ke fail output, anda boleh menggunakan fungsi fputc, menghantarnya aksara yang anda mahu tulis dan penunjuk ke fail output.

    Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 16

    Sekarang kita telah meregangkan rentetan secara mendatar dan menambah penjajaran pada fail output, kita perlu mengalihkan kedudukan semasa dalam fail output kerana kita perlu melompat ke atas penjajaran.

    Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 17
  • Meningkatkan saiz menegak. Ia lebih rumit, tetapi kita boleh menggunakan kod sampel daripada copy.c (copy.c membuka fail output, menulis tajuk pada fail output, membaca imej daripada fail sumber baris demi baris, piksel demi piksel dan menulisnya ke fail output). Berdasarkan ini, perkara pertama yang boleh anda lakukan ialah menjalankan arahan berikut: cp copy.c resize.c

    Untuk meregangkan imej secara menegak bermakna menyalin setiap baris beberapa kali. Terdapat beberapa cara yang berbeza untuk melakukan ini. Sebagai contoh, menggunakan penulisan semula, apabila kita menyimpan semua piksel satu baris dalam ingatan dan menulis baris ini ke fail output dalam gelung seberapa banyak kali yang diperlukan. Kaedah lain ialah menyalin semula: selepas membaca baris dari fail keluar, tuliskannya ke fail output dan selaraskannya, kembalikan fungsi fseek kembali ke permulaan baris dalam fail keluar dan ulangi semuanya sekali lagi beberapa kali.

    Harvard CS50: Tugasan Minggu 4 (Kuliah 9 dan 10) - 18
  • pulih

    Dalam menjangkakan kertas masalah Minggu 4, saya telah menghabiskan beberapa hari terakhir melihat foto yang disimpan dalam format JPEG oleh kamera digital saya pada kad memori CompactFlash (CF) 1 GB. Tolong jangan beritahu saya bahawa saya sebenarnya telah menghabiskan beberapa hari terakhir di Facebook. Malangnya, kemahiran komputer saya meninggalkan banyak yang diingini, dan tanpa disedari, saya secara tidak sengaja memadamkan semua foto! Nasib baik, dalam dunia komputer, "dipadam" biasanya tidak sama dengan "dibunuh." Komputer saya menegaskan bahawa kad memori kini kosong, tetapi saya tahu ia berbohong. Tugasan: Tulis program dalam ~/workspace/pset4/jpg/recover.c yang akan memulihkan foto ini. Hmmm. Okay, ini satu lagi penjelasan. Walaupun format JPEG lebih kompleks daripada BMP, JPEG mempunyai "tandatangan", corak bait yang membantu membezakannya daripada format fail lain. Kebanyakan fail JPEG bermula dengan tiga bait berikut: 0xff 0xd8 0xff Dari bait pertama hingga yang ketiga, dari kiri ke kanan. Bait keempat kemungkinan besar akan menjadi salah satu daripada gabungan berikut: 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,0xe8, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xef. Dalam erti kata lain, empat bit pertama bait keempat fail JPEG ialah 1110. Kemungkinannya, jika anda menemui salah satu corak ini pada pemacu tempat foto disimpan (seperti kad memori saya), ini akan menjadi permulaan fail JPEG. Sudah tentu, anda mungkin menemui ini pada cakera yang mana secara kebetulan; pemulihan data tidak boleh dipanggil sains tepat.

    Bagaimana untuk membuat keputusan

    1. Buka fail dengan kandungan kad memori.

    2. Cari permulaan fail JPEG. Semua fail pada kad ini adalah imej dalam format JPEG.

    Anda sudah mengetahui tentang penanda JPEG: Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 19Adalah penting (dan bagus) untuk mengetahui bahawa setiap fail JPEG disimpan dalam memori sebagai satu blok, dan fail itu sendiri mengikuti satu demi satu. Mari lukis peta ingatan skematik. Setiap segi empat tepat adalah blok 512 bait panjang. Segi empat tepat kelabu ialah kawasan yang tiada fail JPEG; asterisk menunjukkan permulaan fail JPEG. Kami percaya bahawa kami tidak mempunyai blok kelabu antara fail. Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 20Bagaimanakah kita membaca data ini, 512 bait ini, untuk membandingkan permulaannya dengan pengepala JPEG? Kita boleh menggunakan fungsi fread , yang sudah biasa kepada kita, yang mengambil penunjuk kepada struktur data di mana bait baca akan ditulis, serta saiz elemen yang sedang dibaca, bilangan elemen tersebut, dan penunjuk kepada fail dari mana kita membaca data. Harvard CS50: Tugasan Minggu Empat (Kuliah 9 dan 10) - 21Kami mahu membaca 512 bait dan menyimpannya dalam penimbal. Ini akan menjadi penuding &data, dan penuding inptr akan menghala ke fail terbuka dengan kandungan kad memori. Jadi, mari kita kembali kepada struktur fail kita, di mana kita menyimpan
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION