[音樂播放] ZAMYLA陳:這是思嘉小姐 與燭台。 誰是兇手? 好了,我們要找出答案。 在棋盤遊戲線索,你可能 給出一個物理紅色圖像。 而且圖像很紅和 參差不齊,而你的工作是 揭示了隱藏的消息。 通常你用紅色正在提供 放大鏡,或紅色屏幕 揭示隱藏的消息。 嗯,我們要去模仿。 在偵探小說,你給一個位圖圖像 這看起來非常參差不齊,紅色, 然後運行偵探小說程序 露出一個隱藏的信息。 因此,讓我們打破這種分成幾個步驟。 首先,你要打開的文件 - 你已經被賦予了線索。 然後還創建 判決書位圖文件。 然後,你要更新的位圖 頭對於判決結果輸出文件信息。 更多的後來。 然後你要讀入 線索,掃描,逐像素, 改變像素顏色 必要時,和寫作 那些進入判決 - 逐個像素進 判決書掃描線。 我們如何開始準備這件事? 好了,幸運的是,我們有copy.c 在分配代碼。 並且這將證明 非常有用的給我們。 Copy.c打開一個文件,讀取該 INFILE的頭,然後更新 輸出文件的標頭。 然後將其讀出的每個像素中的 掃描線,逐個像素,然後 寫道像素到輸出文件。 所以,你的第一個步驟可能 可以運行下面的 命令,在終端 - CP copy.c whodunit.c。 這將創建的副本 copy.c命名whodunit.c。 所以我們的第一步打開 文件,好了,有一個確切的 的,在copy.c.副本 所以,我將離開你看看那個。 我們現在在這個PSET處理的 文件I / O,基本回吐文件, 閱讀,寫作,編輯它們。 你怎麼先打開一個文件? 好吧,你要申報文件 指針,然後調用 功能打開。 通過在路徑中,或者該名稱 文件,然後您需要的模式 英寸打開該文件 通過在R將打開 foo.bmp閱讀。 而FOPEN與傳遞一個W將 開放bar.bmp,寫文件和 其實編輯它。 所以,現在,我們已經打開的文件,我們 下一步是更新的頭信息 為輸出文件。 什麼是頭信息? 嗯,首先我們需要知道 什麼是位圖。 位圖只是一個簡單的 字節排列。 他們在這個文件正在申報 在這裡,在bmp.h,帶著一幫 一個什麼樣的位圖信息 實際上是做出來的。 但是,我們真正關心的是什麼 位圖文件頭,就在這裡,和 位圖信息頭,在​​這裡。 頭是由一對夫婦 變量將證明是非常有用的。 有成員biSizeImage,這是 以字節為單位的圖像的總大小。 這包括像素和填充。 填充是非常重要的,但 我們將在稍後。 BiWidth代表的寬度 圖像中的像素減去填充。 BiHeight然後還高度 以像素為單位的圖像。 然後BITMAPFILEHEADER和 BITMAPINFOHEADER,正如我所說 早些時候,這些都代表 作為結構。 所以,你不能訪問該文件頭 本身,而是你要得到 這些變量裡面。 確定。 那麼,我們如何更新的頭信息? 嗯,首先我們要看看我們是否 需要從改變任何信息 infile中的線索,到 OUTFILE,判決。 是什麼改變這種情況? 好吧,其實不是,因為我們要去 要只是改變了顏色。 我們不會被改變文件 的大小,圖像的大小,寬度, 或高度。 所以你所有的權利現在 只是複製每個像素。 確定。 所以,現在讓我們來看看如何實際我們 可以從文件中讀取每一個像素。 另一個文件I / O功能 將開始發揮作用 - FREAD。 這需要在一個指向該結構 將包含字節 你正在閱讀。 所以,你正在閱讀到這一點。 然後你傳遞一個大小,這是 每個元素的大小,你 想讀。 這裡,函數sizeof 會派上用場。 然後,你將在數量上,這 表示的元素的數目 大小來讀取。 然後最後,inptr,這是 你是將文件指針 從去閱讀。 因此,所有這些元素都在裡面 inptr和他們要的數據。 讓我們看一個小例子。 如果我想讀入數據兩隻狗, 好了,我可以做到這一點的兩種方法之一。 我可以讀大小的兩個對象 從我inptr的狗,或者我可以讀 在一個對象的兩個狗的大小。 所以你看到,這取決於方式 你安排的大小和數量,您 可以在相同的字節數讀出。 所以,現在,讓我們來改變 因為我們需要的像素顏色。 如果你看看在bmp.h一遍,然後 你會看到在底部 RGBTRIPLEs是另一種結構,其中 它們是由三個字節。 一,rgbtBlue,rgbtGreen和rgbtRed。 所以每一個都代表了額 藍色,綠色的數量,並且 該像素內金額紅色的,其中 每個量是由一個表示 十六進制數。 所以FF0000將是一個藍色的顏色, 因為它從藍色, 綠色,紅色。 然後全F的地址將是白色的。 讓我們來看看smiley.bmp,這 你有你的分銷代碼。 如果您在短短的一個圖像打開它 瀏覽器,那麼你會 剛看到一個紅色的笑臉。 但考慮更深的下潛中,我們將 見,該結構 它僅僅是像素。 我們有白色像素, 然後紅色像素。 白色,FFFFFF,然後將所有的 紅色像素,我在上色為你 在這裡,你可以看到他們是0000FF。 藍零,零綠,全紅。 而且,由於笑臉是8個像素寬, 我們沒有任何填充。 好的。 所以,如果我是分配不同的值 到RGBTRIPLE,我想 使其綠色,那麼我會做的是 我想聲明一個RGBTRIPLE,命名 三,然後進入每 該結構我內字節 會使用點運算符。 所以triple.rgbtBlue,我可以 指派為0。 綠色的,我可以把它分配給全 - 任何 號,說真的,介於0和FF。 再紅,我也想說0。 這樣的話,讓我一個綠色像素。 接下來,如果我要檢查什麼 東西的價值? 我可以有一些檢查 三重的rgbtBlue值是否為 FF和再打印,“我感覺 藍色的!“,作為一個結果。 現在,這並不一定意味著 該像素是藍色的,對不對? 因為像素的綠色和紅色值 也可具有非0值。 所有這意味著,以及所有 這是檢查是 一個完整的藍色。 但是,所有的像素可能也有部分 顏色值,這樣 這裡在下一個例子。 這是一個有點難以看 這個形象是什麼了。 這看起來更有點像 clue.bmp,你會得到。 現在,身體上,你可能會解決這個問題, 因為有大量的紅,由 拿著一個紅色的屏幕圖像,這樣 那其他顏色可以出現。 那麼,我們如何模仿這種用c? 好了,我們可能會刪除所有紅色 從整個影像。 所以要做到這一點,我們會設置每 像素的紅色值設置為0。 這樣一來,圖像會顯得有點 像這樣,在那裡我們有沒有紅色的位 無論什麼。 我們可以看到隱藏的訊息 更清楚現在點點。 它的另一個笑臉。 或者,也許我們可以用另一種方​​法。 也許,我們可以識別 所有的紅色像素 - 也就是說,所有的像素與 0藍色,綠色0和0紅 - 並改變那些白色。 而我們的圖像看起來可能 這樣的事情。 有一點比較容易看到。 有很多其他的方法來發現 秘密消息為好, 處理的顏色處理。 也許你可能會使用的方法之一 我上面提到的。 ,另外,您可能希望 提升一些顏色 並把那些出。 所以,現在我們已經改變了像素 色彩,接下來我們只需要編寫他們 在到該掃描線,逐個像素。 並再次,你要回頭 到copy.c,如果你還沒有被複製 它已經,並期待在fwrite的 函數,它接受數據,一個指針 到包含該字節的結構 你是從,大小閱讀 的項目,項目的數目, 然後outptr - 這些文件的目的。 當您在像素寫,你會 還必須在填充寫。 什麼是填充? 那麼,每一個像素RGBT 是3字節長。 但是,掃描線為位圖圖像 必須的4個字節的倍數。 如果像素的數目不是 多四個,那麼我們就需要添加 這種填充。 填充,只需0表示。 那麼,我們該如何寫,或讀這個? 嗯,事實證明,你不能 其實用fread填充,但你可以 計算。 在這種情況下,線索和判決 具有相同的寬度,所以 填充是相同的。 和填充,因為你會看到 在copy.c,計算 用下面的公式 - bi.biWidth倍的sizeof(RGBTRIPLE)會 給我們多少字節的bmp 有每一行中。 從那裡,模數和減法 與4可以計算出 許多字節必須被添加,使得 在字節倍數 每一行是4。 現在,我們有公式 我們多麼需要填充,現在 我們可以寫它。 現在,我之前提到的, 填充僅僅是0。 因此,在這種情況下,我們只是把 一個字符,在這種情況下為0,進入我們 outptr - 我們的輸出文件。 所以這只能說是的fputc 0,逗號outptr。 所以,雖然我們一直在閱讀到我們的 文件,文件I / O一直跟踪我們 在與一些這些文件的位置 調用的文件位置指示器。 把它看成是一個光標。 基本上,它前進的每一次 我們FREAD,但我們有 控制了這一點。 如果要移動的文件位置指示器, 您可以使用函數fseek的。 其中inptr表示文件 您正在尋找的指針, 量的字節數,你 要移動光標,​​然後從 涉及的基準點 從光標所在處。 如果傳入SEEK_CUR,那 表示當前 在文件中的位置。 或者您可以使用其他一些參數。 所以,我們可能要使用FSEEK跳過 在文件中的填充。 再次,如果你堅持,有 的,在copy.c.一個例子 所以,現在我們已經打開的文件, 的線索,並判決。 我們已經更新了頭信息 我們的判決,因為每 位圖需要的標頭。 我們然後讀入線索的 掃描線,逐個像素,改變 每一個顏色的需要,並 寫那些進入 判決,逐像素。 一旦你打開的判決,你可以看到誰 罪魁禍首,還是什麼秘密 消息。 我的名字是Zamyla,並 這是偵探小說。