Nyiapake kanggo karya
Kaya biasane, pisanan mbukak jendhela terminal lan jalanake perintah kasebut.update50
kanggo mesthekake yen aplikasi sampeyan wis nganyari. Sadurunge miwiti, tindakake iki cd ~ / workspace
wget http://cdn.cs50.net/2015/fall/psets/4/pset4/pset4.zip
kanggo ngundhuh arsip ZIP tugas iki. Saiki yen sampeyan mbukak ls sampeyan bakal weruh yen sampeyan duwe file sing disebut pset4.zip ing direktori ~/workspace . Extract nggunakake printah: Yen sampeyan mbukak printah lsunzip pset4.zip
maneh , sampeyan bakal weruh sing direktori liyane wis katon. Saiki sampeyan bisa mbusak file zip kaya ing ngisor iki: Ayo mbukak direktori pset4 , mbukak ls , lan priksa manawa direktori kasebut ngemot rm -f pset4.zip
cd pset4
bmp / jpg / questions.txt
whodunit utawa "Sapa sing nindakake iki?"
Yen sampeyan wis tau ndeleng desktop Windows XP standar (https://en.wikipedia.org/wiki/Bliss_(gambar)) (bukit lan langit biru), sampeyan wis ndeleng BMP. Ing kaca web, sampeyan bisa uga wis ndeleng GIF. Apa sampeyan wis ndeleng foto digital? Dadi, kita seneng ndeleng JPEG. Yen sampeyan wis nate njupuk gambar ing Mac, mesthine sampeyan wis ndeleng PNG. Waca ing Internet babagan format BMP, GIF, JPEG, PNG lan wangsulana pitakon iki:-
Pira warna sing didhukung saben format?
-
Format apa sing ndhukung animasi?
-
Apa bedane kompresi lossy lan lossless?
-
Endi saka format kasebut nggunakake kompresi lossy?
-
Apa sing kedadeyan saka sudut pandang teknis nalika file dibusak ing sistem file FAT?
-
Apa sing bisa ditindakake kanggo mesthekake (kanthi kemungkinan gedhe) manawa file sing wis dibusak ora bisa dipulihake?
xxd -c 24 -g 3 -s 54 smiley.bmp
Sampeyan kudu ndeleng apa sing kapacak ing ngisor iki; Kita wis maneh disorot ing abang kabeh kedadean saka 0000ff. Ing gambar ing kolom paling kiwa sampeyan bisa ndeleng alamat ing file, sing padha karo offset saka byte pisanan file. Kabeh mau diwenehi ing sistem nomer heksadesimal. Yen kita ngonversi heksadesimal 00000036 dadi desimal, kita entuk 54. Supaya sampeyan ndeleng bait 54 saka smiley.bmp . Elinga yen ing file BMP 24-bit, pisanan 14 + 40 = 54 bait diisi metadata. Dadi yen sampeyan pengin ndeleng metadata, jalanake printah ing ngisor iki: xxd -c 24 -g 3 smiley.bmp
Yen smiley.bmp ngemot karakter ASCII , kita bakal weruh ing kolom paling tengen ing xxd tinimbang kabeh titik kasebut. Dadi, smiley minangka BMP 24-bit (saben piksel diwakili 24 ÷ 8 = 3 bita) kanthi ukuran (resolusi) 8x8 piksel. Saben baris (utawa "Scanline" kang diarani) mangkono njupuk munggah (8 piksel) x (3 bita saben piksel) = 24 bita. Nomer iki kaping papat, lan iki penting amarga file BMP disimpen rada beda yen jumlah bita ing baris ora kaping papat. Dadi, ing small.bmp, file BMP 24-bit liyane ing folder kita, sampeyan bisa ndeleng kothak piksel 3x3 ijo. Yen sampeyan mbukak ing panampil gambar, sampeyan bakal weruh manawa gambar kasebut meh padha karo gambar ing ngisor iki, mung ukurane luwih cilik. Saben baris ing small.bmp mangkono manggoni (3 piksel) × (3 bait saben piksel) = 9 bait, kang ora kelipatan saka 4. Kanggo entuk dawa baris sing kaping 4, iku empuk karo nul tambahan: antarane 0 lan 3 bait kita isi saben baris ing format BMP 24-dicokot (bisa guess apa iku?). Kanggo small.bmp , 3 bait nul dibutuhake, wiwit (3 piksel) x (3 bait saben piksel) + (3 bait padding) = 12 bita, kang tenan kaping 4. Kanggo "ndeleng" padding iki, tindakake ing ngisor iki. xxd -c 12 -g 3 -s 54 small.bmp
Elinga yen kita nggunakake nilai beda kanggo -c saka karo smiley.bmp , supaya xxd mung output 4 kolom wektu iki (3 kanggo kothak ijo lan 1 kanggo padding). Kanggo gamblang, kita wis nyorot kabeh conto 00ff00 ing ijo. Kanggo kontras, ayo nggunakake xxd kanggo file large.bmp . Iku katon persis padha cilik.bmp, mung resolusi 12x12 piksel, yaiku, kaping papat luwih gedhe. Jalanake printah ing ngisor iki. Sampeyan bisa uga kudu nggedhekake jendhela supaya ora transfer. xxd -c 36 -g 3 -s 54 large.bmp
Sampeyan bakal weruh kaya iki: Elinga, ora ana penyimpangan ing BMP iki! Sawise kabeh, (12 piksel) × (3 bita saben piksel) = 36 bita, lan iki kelipatan saka 4. Editor xxd hex nuduhake kita bita ing file BMP kita. Kepiye carane bisa entuk kanthi program? Ing copy.c ana siji program sing tujuane mung kanggo nggawe salinan BMP, sepotong demi sepotong. Ya, sampeyan bisa nggunakake cp kanggo iki . Nanging, cp ora bakal bisa nulungi Pak Boddy. Muga-muga copy.c nindakake iki, mula saiki: ./copy smiley.bmp copy.bmp
Yen sampeyan saiki mbukak ls (kanthi gendéra sing cocog), sampeyan bakal weruh manawa smiley.bmp lan copy.bmp pancen ukurane padha. Ayo dipriksa maneh apa iki bener? diff smiley.bmp copy.bmp
Yen printah iki ora nuduhake apa-apa ing layar, iku ateges sing file pancen padha (penting: sawetara program, kaya Photoshop, kalebu nul mburine ing ends sawetara VMPs. Versi salinan kita discards, supaya ora. sumelang yen ing kasus nyalin BMP liyane sing wis diundhuh utawa digawe kanggo testing, salinan bakal sawetara bita cilik saka asline). Sampeyan bisa mbukak file kasebut ing panampil gambar Ristretto (klik kaping pindho) kanggo konfirmasi iki kanthi visual. Nanging bedane iki mbandhingake byte dening byte, dadi dheweke luwih cetha tinimbang sampeyan! Kepiye salinan iki digawe? Pranyata copy.c ana hubungane karo bmp.h. Ayo dadi manawa: mbukak bmp.h. Ing kana sampeyan bakal bisa ndeleng definisi nyata saka header sing wis kasebut, diadaptasi saka implementasine Microsoft dhewe. Kajaba iku, file iki nemtokake jinis data BYTE, DWORD, LONG, lan WORD, yaiku jinis data sing biasane ditemokake ing jagad pemrograman Win32 (yaiku, Windows). Elinga yen iki ateges alias kanggo primitif sing sampeyan (muga-muga) wis kenal. Pranyata BITMAPFILEHEADER lan BITMAPINFOHEADER nggunakake jinis kasebut. Berkas iki uga nemtokake struktur sing diarani RGBTRIPLE. Iku "encapsulates" telung bita: siji biru, siji ijo lan siji abang (iki urutan kang kita bakal katon kanggo triplets RGB ing disk). Kepiye struktur kasebut migunani? Kanggo rekap, file mung minangka urutan bita (utawa pungkasane bit) ing disk. Nanging, bita iki biasane diurutake supaya sawetara sing pisanan makili soko, banjur sawetara sabanjure makili liyane, lan sateruse. "Format" file ana amarga kita duwe standar, utawa aturan, sing nemtokake apa tegese bait. Saiki, kita mung bisa maca file saka disk menyang RAM minangka array byte gedhe. Lan kita elinga yen bait ing posisi [i] nggantosi siji bab, nalika bait ing posisi [j] liyane. Nanging kok ora menehi sawetara jeneng bita iki supaya kita bisa luwih gampang njupuk saka memori? Iki persis apa struktur ing bmp.h mbantu kita. Tinimbang mikir file minangka siji urutan bita sing dawa, kita ndeleng file kasebut dipecah dadi blok sing luwih bisa dingerteni - urutan struktur. Elinga yen smiley.bmp wis resolusi 8x8 piksel, supaya njupuk munggah 14 + 40 + (8 × 8) × 3 = 246 bita ing disk (sampeyan bisa mriksa iki nggunakake printah ls). Mangkene apa sing katon ing disk miturut Microsoft: Kita bisa ndeleng manawa pesenan penting nalika nerangake anggota struktur. Byte 57 punika rgbtBlue (ora, ngomong, rgbtRed) amarga rgbtBlue ditetepake ing RGBTRIPLE pisanan. Miturut cara, kita nggunakake atribut dikempalken mesthekake yen clang ora nyoba kanggo "tembung kempal" anggota (karo alamat byte pisanan saben anggota dadi kaping 4), supaya kita ora mungkasi munggah karo bolongan ing. struktur kita sing ora ana ing disk ing kabeh. Ayo nerusake. Temokake URL sing cocog karo BITMAPFILEHEADER lan BITMAPINFOHEADER, miturut komentar ing bmp.h. Manungsa waé, wayahe apik: sampeyan miwiti nggunakake MSDN (Microsoft Developer Network)! Tinimbang nggulung luwih akeh liwat copy.c , wangsulana sawetara pitakonan kanggo ngerti cara kerja kode. Kaya biasane, perintah wong iku kanca sejati sampeyan, lan saiki uga MSDN. Yen sampeyan ora ngerti jawaban, Google lan pikirake. Sampeyan uga bisa ngrujuk menyang file stdio.h ing https://reference.cs50.net/.
-
Setel breakpoint ing utama (kanthi ngeklik ing sisih kiwa panguasa kanthi nomer baris utama).
-
Ing tab terminal , pindhah menyang ~/workspace/pset4/bmp , lan ngumpulake copy.c menyang program salinan nggunakake make.
-
Jalanake debug50 copy smiley.bmp copy.bmp , iki bakal mbukak panel debugger ing sisih tengen.
-
Mlaku-mlaku program kanthi langkah kanthi nggunakake panel ing sisih tengen. Wigati bf lan bi . Ing ~/workspace/pset4/questions.txt , wangsulana pitakon:
-
Apa iku stdint.h ?
-
Apa gunane nggunakake uint8_t , uint32_t , int32_t lan uint16_t ing program?
-
Pira bita isine BYTE , DWORD , LONG , lan WORD (Nganggep arsitektur 32-bit)?
- Apa (ASCII, desimal utawa heksadesimal) kudu rong bita pisanan file BMP? (byte anjog, kang digunakake kanggo ngenali format file (karo kemungkinan dhuwur) asring disebut "nomer gaib").
-
Apa bedane antarane bfSize lan biSize?
-
Apa tegese biHeight negatif?
-
Bidang endi ing BITMAPINFOHEADER sing nemtokake ambane warna ing BMP (yaiku bit saben piksel)?
-
Napa fungsi fopen bisa ngasilake NULL ing copy.c 37?
-
Napa argumen katelu kanggo fread ing kode kita padha karo 1?
-
Nilai apa ing copy.c 70 nemtokake padding yen bi.biWidth 3?
-
Apa sing ditindakake fseek?
-
Apa iku SEEK_CUR?
Bali menyang Pak Boddy. ngleksanani:
Tulis program sing diarani whodunit ing file sing diarani whodunit.c sing nuduhake gambar Pak Boddy. Hmmmm, apa? Kaya salinan, program kudu njupuk persis loro bantahan baris printah, lan yen sampeyan mbukak program minangka kapacak ing ngisor iki, asil bakal disimpen ing verdict.bmp, kang drawing Pak Boddy ora rame../whodunit clue.bmp verdict.b
Ayo disaranake sampeyan bakal miwiti ngrampungake misteri iki kanthi nggunakake perintah ing ngisor iki. cp copy.c whodunit.c
Sampeyan bisa uga kaget carane akeh baris kode sampeyan kudu nulis kanggo bantuan Pak Boddy. Ora ana apa-apa sing ora perlu didhelikake ing smiley.bmp , mula nyoba program kasebut ing file iki. Iku cilik, lan sampeyan bisa mbandhingaké output saka program lan output xxd sak pembangunan (utawa Mungkin ana soko didhelikake ing smiley.bmp ? Bener, ora). Miturut cara, masalah iki bisa ditanggulangi kanthi cara sing beda-beda. Sawise sampeyan ngenali gambar Pak Boddy, dheweke bakal ngaso kanthi tentrem. Wiwit whodunit bisa dileksanakake kanthi pirang-pirang cara, sampeyan ora bakal bisa mriksa kabeneran implementasine nganggo check50 . Lan supaya spoil fun sampeyan, nanging solusi asisten uga ora kasedhiya kanggo masalah whodunit . Pungkasan, ing file Ing ~/workspace/pset4/questions.txt , jawab pitakonan ing ngisor iki: Whodunit? //ктоэтосделал?
ngowahi ukuran
Nah, saiki - tes sabanjure! Ayo nulis program sing diarani resize in resize.c . Iku bakal ngowahi ukuran gambar BMP 24-dicokot uncompressed ing langkah n. Aplikasi sampeyan kudu nampa persis telung argumen baris perintah, kanthi nomer siji (n) minangka integer ora luwih saka 100, sing nomer loro yaiku jeneng file sing bakal diowahi, lan nomer telu yaiku jeneng versi sing wis disimpen. berkas.Usage: ./resize n infile outfile
Kanthi program kasebut, kita bisa nggawe large.bmp saka small.bmp kanthi ngowahi ukuran sing terakhir kanthi 4 (yaiku, nikelake lebar lan dhuwur kanthi 4), kaya ing ngisor iki. Kanggo gamblang, sampeyan bisa miwiti tugas kanthi nyalin copy.c./resize 4 small.bmp large.bmp
maneh lan menehi jeneng salinan resize.c . Nanging pisanan, takon dhewe lan njawab pitakonan iki: apa tegese ngganti ukuran BMP (sampeyan bisa nganggep yen n kaping ukuran infile ora ngluwihi 232 - 1) . Temtokake kolom ing BITMAPFILEHEADER lan BITMAPINFOHEADER sing kudu sampeyan ganti. Coba apa sampeyan kudu nambah utawa mbusak kolom scanlines . Lan, ya, matur nuwun yen kita ora njaluk sampeyan nimbang kabeh kemungkinan nilai n saka 0 nganti 1! (sanajan, yen kasengsem, iki masalah saka buku hacker kang;)). Nanging, kita nganggep yen kanggo n = 1 program bakal bisa digunakake kanthi bener lan file output file bakal padha karo infile asli. Apa sampeyan pengin mriksa program nggunakake check50? Ketik printah ing ngisor iki: ~cs50/pset4/resize
Inggih, yen sampeyan pengin ndeleng, contone, header
large.bmp (ing wangun sing luwih ramah pangguna tinimbang xxd ngidini), sampeyan kudu nglakokake printah ing ngisor iki:
~cs50/pset4/peek large.bmp
Malah luwih apik, yen sampeyan pengin mbandhingake sampeyan header karo header file asisten CS50. Sampeyan bisa mbukak perintah ing direktori
~/workspace/pset4/bmp (mikirake apa sing ditindakake saben printah). Yen sampeyan nggunakake
malloc , priksa manawa sampeyan nggunakake
gratis kanggo nyegah bocor memori. Coba gunakake
valgrind kanggo mriksa bocor.
./resize 4 small.bmp student.bmp
~cs50/pset4/resize 4 small.bmp staff.bmp
~cs50/pset4/peek student.bmp staff.bmp
Kepiye carane mutusake?
-
Bukak file sing kudu digedhekake, lan uga nggawe lan mbukak file anyar ing ngendi gambar sing digedhekake bakal direkam;
-
nganyari informasi header kanggo file output. Amarga gambar kita ana ing format BMP lan kita ngganti ukurane, kita kudu nulis header file anyar kanthi ukuran anyar. Apa sing bakal diganti? Ukuran file, uga ukuran gambar - jembar lan dhuwure.
-
Kita maca file metu, baris dening baris, piksel dening piksel. Kanggo nindakake iki, bali menyang perpustakaan I / O file lan fungsi fread. Butuh pointer menyang struktur sing bakal ngemot byte sing diwaca, ukuran unsur siji sing bakal diwaca, jumlah unsur kasebut, lan penunjuk menyang file sing bakal diwaca.
-
Kita nambah saben baris kanthi horisontal miturut ukuran sing ditemtokake, lan nulis asil menyang file output.
Kepiye carane nulis file? Kita duwe fungsi fwrite, sing menehi indikator menyang struktur ing ngendi data sing bakal ditulis ing file kasebut, ukuran unsur, nomer lan pointer menyang file output. Kanggo ngatur loop, kita bisa nggunakake loop for sing wis kita kenal .
-
Isi ing longkangan! Yen jumlah piksel ing baris ora kaping papat, kita kudu nambah "alignment" - nul bita. Kita butuh rumus kanggo ngitung ukuran alignment. Kanggo nulis bita null menyang file output, sampeyan bisa nggunakake fungsi fputc, maringaken karakter sing pengin ditulis lan pointer menyang file output.
Saiki kita wis digawe dowo senar horisontal lan nambah alignment kanggo file output, kita kudu mindhah posisi saiki ing file output amarga kita kudu mlumpat liwat alignment.
-
Tambah ukuran vertikal. Luwih rumit, nanging kita bisa nggunakake kode sampel saka copy.c (copy.c mbukak file output, nulis header menyang file output, maca gambar saka file sumber baris dening baris, piksel dening piksel, lan nulis mau. menyang file output). Adhedhasar iki, ing bab pisanan sampeyan bisa nindakake iku mbukak printah ing ngisor iki: cp copy.c resize.c
Kanggo nggedhekake gambar kanthi vertikal tegese nyalin saben baris kaping pirang-pirang. Ana sawetara cara kanggo nindakake iki. Contone, nggunakake rewriting, nalika kita nyimpen kabeh piksel siji baris ing memori lan nulis baris iki kanggo file output ing daur ulang minangka kakehan minangka needed. Cara liya yaiku nyalin ulang: sawise maca baris saka file sing metu, nulis menyang file output lan nyelarasake, bali fungsi fseek bali menyang wiwitan baris ing file metu lan baleni kabeh maneh kaping pirang-pirang.
-
Bukak file kanthi isi kertu memori.
-
Temokake wiwitan file JPEG. Kabeh file ing kertu iki minangka gambar ing format JPEG.
waras
Kanggo nunggu kertas masalah Minggu 4, aku wis ngenteni sawetara dina kanggo ndeleng foto sing disimpen ing format JPEG dening kamera digital ing kertu memori 1 GB CompactFlash (CF). Aja ngomong yen aku wis ngentekake sawetara dina kepungkur ing Facebook. Sayange, katrampilan komputer saya akeh sing dikarepake, lan tanpa ngerti, aku ora sengaja mbusak kabeh foto! Untunge, ing jagad komputer, "dibusak" biasane ora padha karo "dipateni." Komputerku ngeyel yen kertu memori saiki kosong, nanging aku ngerti yen ngapusi. Tugas: Tulis program ing ~/workspace/pset4/jpg/recover.c sing bakal mbalekake foto kasebut. Hmmm. Oke, iki klarifikasi maneh. Sanajan format JPEG luwih rumit tinimbang BMP, JPEG nduweni pola byte "tanda tangan", sing mbantu mbedakake saka format file liyane. Umume file JPEG diwiwiti kanthi telung bita ing ngisor iki:0xff 0xd8 0xff
Saka bait pisanan nganti katelu, saka kiwa menyang tengen. Byte kaping papat bakal dadi salah siji saka kombinasi ing ngisor iki: 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,0xe8, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xed, 0xee, 0xed. Ing tembung liya, papat bit pisanan saka bait kaping papat saka file JPEG yaiku 1110. Kemungkinan, yen sampeyan nemokake salah sawijining pola kasebut ing drive ing ngendi foto disimpen (kaya kertu memori), iki bakal dadi wiwitan file JPEG. Mesthi wae, sampeyan bisa uga nemoni disk kasebut kanthi sengaja, pemulihan data ora bisa diarani ilmu sing tepat.
GO TO FULL VERSION