2009年11月30日 星期一

HW4



寬度 210個像素
高度164個像素
水平解析度 72 dpi
垂直解析度 72 dpi



2009年11月29日 星期日

HW4


這次作業是要像第三次作業那樣將讀進來的

圖檔資訊顯示在C++ Builder的影像元件上但不要

使用BCB裡面提供的LoadFromFile的方式來讀檔

是要使用第三次作業有用到的fopen fread fseek的方式

來直接讀取圖檔的檔頭 讓讀進來的圖檔大小 圖檔長寬等都能顯示出來

在之前的課堂上老師有解釋了BMP檔案格式的特色

和BMP檔頭內的每個byte所提供的訊息

先使用fopen開啟所要使用的圖檔

透過fseek將指標指向我們要的檔頭資訊

再配合fread來讀取我們的檔頭訊息



就可以將開啟的圖檔資訊輸出在BCB的元件上

整體看起來也比之前HW3開啟圖檔時不斷跑出

圖檔的資訊的視窗來的簡潔有力

在做作業的期間一度忘了BMP的檔頭內所要讀取的有哪些資料

就使用老師之前推薦的PSPad這套軟體和wikipedia所查到的

BMP檔頭內容來複習 基本上只要前面幾次作業都有理解的話

這次作業還真的不算難~

HW4

fopen , fseek , fread ...必須利用這一些指令 , 來完成讀檔並且把檔案的內容讀出 .

不用LoadFromFile的方式讀檔 , 就感覺非常的麻煩 , 因為要用pspad去找他記憶體的位置 ,

然後再用fopen , fseek , fread 來把它讀進去並且掃出圖來 .




fseek(imBMP,38,SEEK_SET);

fseek(imBMP,42,SEEK_SET);


有這兩段程式碼可以顯示水平解析度跟垂直解析度 ,

可是我不知道為什麼的竟然是顯示 0 ,

後來我跟同學對了一下程式碼 , 發現除了變數名稱以外 , 其他的我都跟他一樣阿 ,
我不斷的在檢查我的程式碼 , 可是程式碼就是完全一樣了 ,
但是我的水平解析跟垂直解析就是顯示不出來 ,
後來我直接將他的程式碼貼到我這邊後 ,
就發現竟然可以出來了 , 不知道是不是在運算過程中吃進了空白 ?
所以才會使我的水平解析跟垂直解析不斷顯示 0

HW4

上圖是一開始要掃出來的圖檔(點圖可放大)
上圖是我掃出來ㄉ圖檔(點圖可放大)



在做這個作業時,本來是想直接用之前的程式去讀圖的,不過這一讀出來就給他感覺是個非常擠的畫面,所以我上來看了看學長們上傳的HW4發覺完全沒有我那個問題,所以我就乾脆用老師上課說的那個PageControl來給他排版整齊一下,讀出來感覺上就比較沒有之前那麼擠了,這周的作業是要我們用fseek. fread....來做掃圖的動作 ,在掃圖期間有點嚇到,我原本以為是會直接蹦的圖就出來了,沒想到它是慢慢得從下往上出現,這是我覺得有趣的地方,因為一般像是網頁上的圖它都是由上往下出現的 ,幸好它圖掃的時候不會很慢,掃太慢那還得了= =。

剛開始在做作業時,發現為什麼一直沒辦法把圖給讀出來呢?之後回去看了一下之前所寫過的fopen.fseek.fread...的部份時,這才發現錯的地方只是差在讀的地方讀錯了,難怪一直都沒有讀出圖片在我想要的地方去,其實有一些部份還不是很了解,不過還好有把之前的作業檔案留著,不然就幾乎整個程式碼久了之後應該就會變得模模糊糊了。

HW4

此次程式作業目標是在讀取一張 BMP 影像, 並將其影像內容顯示於 C++ Builder 的影像元件之中。實做時候開始建立程式介面和對話按鈕。
面對不少讀取BMP檔案問題,是需要去面對了解。
怎樣把一張照片載入之後,再點選讀取按鈕,設定原件安排和撰寫code,
用結構struct方式宣告,之後用來檢視檔案的原始內容,

在程式執行上覺得奇怪的地方,是兩個圖片非常相似,似乎沒什麼變化
就可以得到想要照片執行結果,加入自己的想法和概念,
建立能轉換圖片位元及讀取的函數以及圖片對話窗語法。
只是稍微內部程式碼修改一下,但看似簡單的動作,實際上並不是如此
最後才了解到搭配在一起的應用程式。
圖片來源: flickr

2009年11月28日 星期六

HW4

這次是第四次作業了,這次所做的主題是不用LoadFromFile的方式,而是用fopen,fread,fseek去讀取圖檔的資料後把圖給掃出來,而要做到這點,又需要用到PSPad這個軟體去檢查他的原始碼,跟之前一樣,WIKI上有指的位置的相關資訊,想看的請按這裏

在做這次的作業之前,有礙於之前的版面實在是太小了,讓我的圖顯示出來的時候都要用滾輪一直拉,這點真的是很麻煩,在看了老師上了的程式之後,我也用PageControl元件來將畫面進行分面,這個元件在課本中7-27頁有詳細介紹,所以在這我就不多說了,不過我的排版還需要再調整...個人覺得分頁之後看圖是不錯啦...結果Information那塊變得很空...看了很不習慣= =








這是我程式的新界面,看起來空空的,實際上都用PageControl分掉了。

在上課的時候老師有說明讀檔的位置,當下在教室作的時候遇到很有趣的問題,一般來說大家都會認為讀一張圖的時候是從左上角的RGB開始,但在實做出來的時候卻是從下方。


在PageControl分頁Cfile中進行讀圖(點圖可放大)。在這邊的畫面我是用動態宣告一個畫布,讓他可以自行去讀取圖的Width與Height,而動態新增一個影像元件的方法在老師的C++ Builder部落格中有介紹。這邊要說一下,很多人都有跟我遇到相似的問題,就是在動態宣告影像在ScrollBox之後影像會被裁掉,麻煩大家注意一下是否有在ScrollBox裡面多新增了一個影像元件,這會造成輸出的動態影像必須依照Image的大小來決定他的範圍,這樣反而會限制住圖的大小,所以切記啊...ScrollBox裡不要再多新增Image了...



掃完啦!!其實用這種方式的速度跟LoadFromFile開的速度差不多,不過在程式碼中就比較麻煩,因為RGB要3個為一組,所以我是設一個變數後在迴圈中+3來控制他。不過,如果不設變數的話,照道理來說程式應該會自己往下抓點才對,但是,如果將變數刪掉的話他卻掃不出來,這點倒是讓我很疑惑,不知是我的問題還是程式本身出錯。

2009年11月27日 星期五

HW4

寫這一次的作業比之前的作業要花上不少時間。

以下是錯誤圖片:


















因為右邊的圖片一直掃不出來,

讓我一直在找程式碼中的錯誤,

雖然程式也才幾行而已,

但是時間卻全花在找出掃不出圖的原因,

後來發現是這一行,

Image2->Canvas->Pixels[j][i]=(TColor)RGB(col[0],col[1],col[2]);

因為掃圖的方式

所以必須將Pixels[j][i]改成Pixels[j][iImageHeight-1-i]

而且又因為RGB讀進的次序必須將(TColor)RGB(col[0],col[1],col[2]);

改成(TColor)RGB(col[2],col[1],col[0]);

所以改完成後應該是

Image2->Canvas->Pixels[j][iImageHeight-1-i]=(TColor)RGB(col[2],col[1],col[0]);

之後掃圖就沒有問題了。

以下是正確版:

2009年11月26日 星期四

hw04

















這次的作業,是要自己將圖片影像讀出來
讀完每個點的RGB再將其顯示在畫布上就大功告成了
其實這個作業跟之前的作業有相似之處,
如果稍微想一下就可以完成了
因為是要將每個點的RGB值讀出來
所以先用個for迴圈,再將其讀出的長寬設給變數
變成其FOR迴圈的條件,

for(j=iFileHeight;j>0;j--)
for(i=0;iCanvas->Pixels[i][j]=(TColor)RGB(bSize[2],bSize[1],bSize[0]);
offset=offset+3; //記憶體存放位置 以3個BIT(RGB)為一個像素
}
這樣就可以成功將圖片讀出來囉,大功告成。

對於原本搞不懂記憶體存放位置等相關資訊的我弄了好久,
用pspad去看,加上老師上課提到的資訊拼拼湊湊,
終於懂9成了,我還發現如果使用另存新檔方式存放的圖片不能順利開檔(jpg->bmp),
有些同學好像也會,自己去猜好像是因為jpg檔式壓縮方式儲存的,所以轉檔可能會造成讀檔有問題(純屬猜測)。

最近,我覺得上課提問題很重要,
因為會提問題代表著自己知道哪邊不懂,意味著自己有去思考,
只是平常的我都不太敢問,但看著班上同學都會找老師問問題,
自己不禁也提起了勇氣把不懂的地方向老師請教,
我知道,
如果真的懂了,那種成就感是很快樂的。

HW4

作業邁向第四次
一直不斷加上去的功能讓整個程式碼變的很雜亂
雜亂的原因是由於我致力於架構出"像樣點"的Software
所以大量用到顯示/隱藏可使用/不可使用的屬性

例如:
之前的開啟圖檔後Show informations或轉成grayscale的功能
為了避免尚未load image就按下Buttom而造成錯誤
所以在load image前,Buttom屬性是設定成Disable的

當功能越多,判斷越多,開關越多的情況下
每每一個Buttom_click的function就要先佔掉一面的控制開關
不知道有沒有辦法可以好好整頓整頓那些雜亂的開關..


而這次作業上一次課堂上就做出來了
老實說是不經意的抓以前的程式碼變造的
//為什麼說不經意..原因有二
//一是因為我都是在筆電上處理BCB,而那個禮拜沒帶
//程式碼都在筆電裡,要重新拉出一堆物件
//還沒開始作作業應該都要下課了..
//另一個原因是期中考殺很大的必修要看不完了
//實在沒心思去寫程式,後來書越看越煩所以又跟同學借程式來試作

也因為沒有遇到什麼大到難以克服的問題
所以我認為是不怎麼困難的
倒是後來老師提出來的疑問還真的讓我咦了好大一下


fseek指向,然後用fread讀後
指標應該是理所當然的指向讀取的最後一個byte尾
但是如果把fseek抽離構圖迴圈,單留fread在裡面讀
會發生無法預期的狀況,解釋不出來的現象,還頗匪夷所思的...


因為電腦在期中考週的前一天故障
造成這個作業沒有充分的時間達到自己架構的模樣
(補充:作業五已實現)


程式初始如下:
從MainMenu選擇繪圖...就會讀取設定好的指定位置的檔案,開始繪圖















(畫到一半的時候)















讀檔完成後會一併Show出檔頭資訊
















比較要注意的地方應該是Bitmap檔頭奇異的儲存格式:
1.順序不是以R, G, B方式排序,而是以B, G, R排序
2.儲存的像素點是從左下到右上
(這尤其奇怪的,Image的左上座標是(0,0),右下是(X_MAX,Y_MAX)
就算是(0,0)倒反,也應該是從(X_MAX,Y_MAX)到(0,0)
但是這是題外話,一開始就沒有被這個排序規則搞到
因為找到了色彩值的檔頭位置後
為了要確定的確是某像素點的顏色
就組合起來比對,一下就發現像素點是從左下開始向右排序
)


原本的計畫是:
在繪圖的時候開啟一個新的Form或Frame來做繪圖的動作
繪圖完成後再把圖像Load到Image的物件中
再另外彈出一個Form/Frame來Show檔頭資訊
這部分還要稍微Serch一下參考範本;


而開啟的檔案路徑目前是寫死的
理想中是拉一個textbox讓使用者輸入檔案路徑
不過這樣一來雖然程式變的較人性化
但是要使用者輸入檔案路徑好像也是件麻煩事
因為要預防格式輸入錯誤去做判斷
而使用者要自己輸入路徑+檔名用起來也很不方便

HW4




在這次的開BMP圖檔的作業中,是要以C語言中檔案存取的指令(fopen,fread,fseek...)來開啟,
而不是使用c++builder裡所內建的Image1 -> Picture -> LoadFromFile...來開檔。
我們在之前的作業三當中已經利用fopen,fread,fseek指令來讀取圖檔資訊(檔案大小,圖片高寬等等)
若想要將影像秀出螢幕上,我們勢必要先讓fseek指標指到影像原始碼的位置(原始碼的部分可由PSPad這套軟體來檢視),
然後再用fread去讀,我們讀到的東西會先擺入一個陣列中,陣列有3個空間分別來擺放色彩R,G,B值,而這RGB值就可以表示一個像素"點",不過程式只這樣寫還不夠,如此讀到的只有一個像素點而已,因此我們必須要用兩個迴圈來寫,外迴圈是跑圖的高的部分,內迴圈是跑圖的寬的部分,而程式的大鋼就是如此。

在這次的作業中,fopen,fread,fseek這些指令經過前面幾次的練習都熟悉的差不多了,沒有甚麼大困難
,而比較會有問題的地方大概會在讀檔時該用怎樣的讀法?一次讀幾個byte?讀到的東西該暫存到怎樣的資料型態?然後在怎樣丟入image中?丟完後指標該怎麼指?

基本上這些問題排除了,那程式也差不多會寫了,其實程式還滿短的,自己寫完後也覺得不算太難!

2009年11月25日 星期三

HW4













其實上上星期上課的時候就懂用fopen去讀整張圖的RGB組成 然後印在image上的觀念


但是fseek(imBMP,offset,SEEK_SET)


和 Image1->Canvas->Pixels[j][i]=(TColor)RGB(R,G,B)

這兩行程式讓我很無法理解,嘗試很多不同方法才找到解法

(1)首先fseek那邊最大的問題出在offset的設置一開始我用for迴圈從54開始跑,每跑完一次就執行offset+=6;範圍設<=圖長*寬+54,因為我以為fread(bsize,1,6,imBMP)是代表一點RGB占掉6個位元組,但發現這完全不對,後來找到問題是因為圖片每一點的RGB組成是由3個位元組來定義,所以正確的設置for迴圈是要讀取到一點RGB後,offset+=3,範圍設<=圖的長*寬*3+54才正確,往後才可以正確讀取到下一點RGB

(2)而第二個問題是Pixels[j][i], i 和 j 的設定,我只知道BCB的點和VC的行列剛好顛倒,但實際去描點的時候發現圖會整張呈現非常詭異的情況











就只能說跟我想像的完全不一樣,老實說我也不懂問題出在哪,最後是看著圖想像程式碼的執行狀況去修改 i , j 的值 (這樣講好像有點豪洨..) 不過我真的不懂BCB她是怎麼描點的 希望這部分老師可以詳細講解 , 因為我設定的數值就是跟圖完全相反的方向(也就是跟我以為正常的方向相反)就好像是倒過來描的(不好意思 我不太會解釋)

這次程式可以說我是碰巧打出來的... 因為我也不太懂為什麼這樣會正確,另外還有一點,我描出來後圖會有色差 不知道在網路上PO圖看不看得出來,這點我也不知道怎麼解釋,希望老師可以就這幾個來解釋 感謝!!

-----------------------------------------------------------
09.11.26更新
-----------------------------------------------------------

今天上課的時候問完老師大概懂問題出在哪了!!


問題1.原來fread(bSize,1,6,imBMP)我根本讀錯了,RGB只有三個bytes,
改成fread(bSize,1,3,imBMP)就對囉!!也解決色差的問題 happy~~




問題2.為什麼圖顯示出來會整個顛倒?? 老師說圖檔的RGB會有兩種存放的方式 一種是從前面開始放,另一種是從後面開始放,所以不是描點的問題,是BMP檔她裡面本來就會有不同的存放方式


終於解決了昨天的兩個問題 不過今天發現另一個問題!!!





我讀取了三張圖檔 第一張最大(下面露出馬腳) 第二張中等覆蓋在第一張上面
第三張是左上的小紅傘
我嘗試過修改掉這個小缺點,我拉了一個Button 來做delete Image1的功能
按下去後圖檔確實會消失,但當我再次讀取圖檔的時候發生了下列的錯誤!!
然後指向Image1->Cavas->Pixels[i][j]....的這行程式碼(此為描點的程式碼)
希望老師或同學能告訴我問題出在哪,希望能解決圖檔重疊的問題

HW3













這次作業是要把BMP的圖檔讀出,這是我設計的程式草稿。用上一次作業的程式改的,看著程式功能越來越多,就會有種得意的感覺,但這些都只是一些皮毛而已。 由於沒吸收到課堂上的資訊,程式打起來非常吃力,只能看著範例程式,慢慢研究了解。



















上網看了BMP圖檔的頭檔資料,從0開始的2個位元組是顯示點陣圖文件的標示符BM,再來是4個位元組來顯示各項資料,維基百科標示了15組,而我簡單顯示8組資料。bsize[0]+bsize[1]*256+bsize[2]*256*256+bsize[3]*256*256*256可以把以4個位元組顯示的資料顯現在程式裡。


















這是執行的結果,一開始執行的時候遇到一點困難,就是頭檔資料顯示一直不正確,dword 一直都只有第一個數字有值,其他都0。後來發現是我fread函數參數設錯,果然寫程式前要先了解函式的結構啊,這次還用到了fopen 和fseek C語言的函式,學的越來越多要記的也越來越多,這也是好事啊!

2009年11月6日 星期五

HW3

1

這次作業花了我很多時間在處理跟程式寫作無關的東西
因為這次要使用最原始的C語言去開一個BMP圖檔
為了避免與之前做的檔案混淆或是部分功能衝突
重新思考必做一個新的UI

Program Name:SourceBMP
Version:         0.01 alpha
功能:
讀取BMP的檔頭資料,並將其顯示出來

有興趣的人可以從這裡下載執行檔

這幾個禮拜老師要我們透過fopen fseek 與fread去開啟一個BMP檔案
讓我回去翻找高中時學習C的記憶
加上網路上查詢相關指令說明
馬上就能將圖檔載入並將部分檔頭輸出

指令說明:

fopen
這個是一在C語言中用來開啟檔案的指令,使用前必些要先載入stdio.h並用FILE * 變數去使用
使用方式
fopen("檔名","開檔的方式");//開檔方式分別有r w a r+ w+ a+
ex: fopen("abc.txt","r")
因為太久沒有用過所以一開始開檔方式直接用w
結果造成BMP的原始資料被破壞
與老師研究弄老半天才發現這個問題
所以以後透過fopen開檔時一定要注意自己的使用需求

fseek
這個可以直接指定要從檔案哪個地方讀取
使用方式
fseek(檔案的變數名稱,位置,位置從哪個地方算起);
ex: fseek(file,1,SEEK_SET);
第三個參數有三種方式可選擇
SEEK_SET從開頭
SEEK_END從結尾
SEEK_CUR目前的指標位置(這個沒有試過)

fread
這個是用來抓取檔案資料的通常搭配fseek使用
使用方式
fread(抓取資料後放置的空間,抓幾個byte,總共抓幾個byte,抓取資料的位置)
ex: fread(buf,1,2,file);

以上都是我參考一些文件後的心得,不曉得有沒有錯

講完了指令
現在要講得是我在寫程式時遇到到的問題
因為我是使用C++Builder2010(BCB的新版本)
一開始在fopen裡面直接寫絕對路徑時都沒問題
但將路徑改為動態抓取時
原本的fopen(OpenPictureDialog1->FileName.c_str(),"r");
Compile不會過
2 
一直卡在這個問題
後來透過BCB給的錯誤訊息上網爬文
才知道自從BCB2009版以後加入了Unicode的問題
官方為了解決這個問題後來又另外洗了一個叫t_str()的函數
所以2009版以後要改成fopen(OpenPictureDialog1->FileName.t_str(),"r");
這樣才能完整的通過
至於為啥官方要這樣做網路上的資料並不多
或許改天自己研究一下這個函數的原型

解決了檔案名稱的問題
接下來就是重頭戲讀取BMP檔頭資料
3png
BMP的組成如上圖所示
第一區塊儲存的像是檔案類型 檔案大小等

第二區塊儲存的像是檔案長寬 位元格式等
詳細資料都能在wiki上找到

第三區塊儲存的是色彩的索引值為4的倍數儲存
不夠的話會以0補齊

第四區塊就是記錄圖檔每個像素點的顏色資訊

其實這次程式不難
把BMP格是文件與指令文件看得懂
並套用老師給的結構
程式就只要注意不要抓錯位置就好了
難在是根本不肯去做

很多問題的解決方式網路上或是鍵盤上按F1都可以找到相關訊息
資訊日新月異
學資工的就是要多多涉獵各東西
就算沒聽過也要有最基本的查資料能力
如果說這都沒有
每天只會耳邊聽耳機,左手遊戲機or手機,右手滑鼠Facebook
然後只會抱怨機器很爛等等
這些都不是理由
重點是有沒有心而已
有心要把程式寫好的話就算沒有電腦
隨便拿張紙片都能寫下腦袋中的想法

我自己也有類似的體驗(睡覺時腦袋還在想 醒來就OK了)
以上這小段純粹是自己看到別人的情況外加努力去做事卻跟著被老師錶三節課的感想以及抱怨
為何乖乖做事的人總是會跟著被罵勒? 此題真的是無解阿~

WH3



老師這禮拜要我們把BMP 影像的檔頭資料讀出來,一開始看了老師的示範檔,感覺一切都很順利,但是BCB的環境畢竟跟C++不太一樣,再說我C++也學的不扎實,所以一開始就讓我攪盡腦汁,最後經過查老師的檔案在找一下資料用了fopen(OpenPictureDialog1->FileName.c_str(), "r"),讓我成功的用了選單。
檔案大小int IFileSize = bSize[0] + bSize[1] * 256 + bSize[2] * 256*256 + bSize[3] * 256*256*256;
圖片的寬int ImageWidth = bSize[0] + bSize[1] * 256 + bSize[2] * 256*256 + bSize[3] * 256*256*256;
圖片的高int iImageHeigh= bSize[0] + bSize[1] * 256 + bSize[2] * 256*256 + bSize[3] * 256*256*256;
這些程式碼雖然我ㄧ開始都不太會寫,但聽了老師解說在去了解一下其實也不是想像的這麼困難的,可是fopen fseek fread這三個我還是不太懂.....查了一些資料好像是點陣圖頭的位元組的位子,可是就是想不通她好像是為了讀圖檔所創的...好難喔,他們的差別和公用我想也是這次作業的重點,還要再找找資料問問同學了!

HW3


這一次的作業遇到了些小問題,像是一開始宣告的 char cBuffer[8],假如宣告成
char cBuffer[20],在抓標頭檔時,就會抓到後面的一些資料,而顯示出亂碼,而且也不知道為什麼,假如我把桌面畫面剪下來,存成BMP檔,在用程式開起來,結果顯示出來的H_resolution和V_resolution,都會是零,假如用網路上的圖,都可以顯示得出來,這是為什麼?

HK3

昨天上課又再一次的被精神喊話
老師給我們看一位工程師寄信專程來問老師題目
也想到自己也已經大四了~~~
聽老師說程式設計的重要
讀資工的不會寫程式要會什麼?
又想了一下自己程式會了多少?
想一想自己不知不覺這樣四年就過去了~
換來的卻不知道學了什麼東西?
每個領域都是東會一點西會一點
而沒有一個是專精的
這一次的作業是要我們會讀取一張圖片的內容所有資訊
從檔案大小到長、寬、水平深度、垂直深度等...
所用的指令fseek,fread,fopen
fopen是要開啟檔案
fseek是要只一個檔案的指標
fread是把記憶體的struct填滿
當老師昨天在看每一位同學所弄得作業
都是把檔案的內容以另一個視窗顯示出來
而要我們做的是要用label顯示
當老師在看每一位同學的作業時
就在想要顯示在label上面
是不是把showmessage改成label就好了
果然當給我們寫的時候裡面的程式主不過稍做修改就成功了~試過果然信心大增
回家想上次的灰階跟這一次的成是結合在一起感覺怕怕的
果然一開始又出現了上一次無法顯是灰階圖片的問題
又逐一的檢查程式碼再去改總算成功了
並且聽到老師說要能看出其他想關的內容解析度
果然把原本的去除以39.37就得到了72這個數字
但不知道為什麼位元深度卻照自己想法去做卻得到0
怎麼改都不對~
而且不知為什麼label的中文字為什麼會被殺掉一點點
明明就有拉長為什麼還是這樣?
還要再研究啦~~~~

hw3

這次作業用到fopen來讀取圖片資料的相關資訊。因為是第一次接觸fopen,剛看到老師的範例程式碼,當然是看不懂,但聽了老師講解和上網找資料後,慢慢的了解要如何來讀取圖片資料。

HW3


這次的作業是在label上把檔案的格式 大小 以及長寬險是在上面,上次老師在課堂上所做的是開啟檔案之後,他會直接一個一個SHOW出檔案的相關東西,這次則是叫我們回家把他放在Label上顯示出來。


一開始老師在講fopen,fseek,fread這些東西時,其實我不不太了解,上課看了老師的範例把程式碼打了一次,回家又做了一次,多少有比較了解到這些東西的公用,在上次的課堂上老師也有說明fopen,fseek,fread是做什麼用的,據我上課所聽到的,foprn是把東西放到記憶體當中然後fseek是他走的路徑的方法,fread就是讀取內容,這是我的認知,不知道有沒有錯。

HW03

















這次作業是要將圖片的詳細內容給讀出來,
聽到老師說要讀記憶體位置,對於記憶體位置,真的有點給他搞不懂。

今天主要的課程是要使用fopen,fread,fseek。
老師說這是最基本的幾個指令
對於初學的我只能上網去查資料了
唯一有接觸過的只有fopen,用來開啟檔案,並且配合fclose來將指令關閉,避免浪費記憶體。
fread表面看起來就是"閱讀",沒錯!他就是閱讀fread(變數名稱,幾次,幾個,檔案名稱)
fseek則是尋找,我們這次得作業是拿來尋找要讀的記憶體位置的開頭,以指標的形式將他指向讀檔的開頭 fseek(檔案名稱,記憶體存放位置(開頭),SEEK_SET(指向這裡))
fseek先是將要讀記憶體的位置找到後,在使用fread將資料讀出來。
瞭解了大概做法之後就開始實做了
設變數部分我參考老師的設法,有使用byte、int、char
在課堂上其實我不是很了解這些設定的方式
是回到宿舍後才了解的,byte拿來接收讀到的byte
可能是沒用過吧 還真是不習慣。
接著就開始尋找讀檔位置了
聽老師說,可以在維基找到記憶體儲存位置
當然就上了維基
也找到了相關的記憶體存放位置
然後利用fseek將裏頭的資料取出來 ,接著就將它顯示在label中 。
其中:水平解析度和垂直解析度我卻讀不出來
當下也詢問老師,老師使用pspad將記憶體的存放圖show出來,發現維基上的存放位置竟然在pspad上出現是空的!! 這個地方我就不太懂了。
BYTE bSize[4]={0,0,0,0};
int iFileSize,iFileWidth,iFileHeight;
char cBuffer[3];
OpenPictureDialog1->Execute();
Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName) ;
FILE *fp; //宣告檔案名稱
fp = fopen(OpenPictureDialog1->FileName.c_str(),"r") ; //檔案名稱,"r"//閱讀

fread(cBuffer, 1, 2, fp); //讀標頭檔
Label8->Caption=cBuffer;

fread(bSize, 1, 4, fp) ;
iFileSize = bSize[0] + bSize[1] * 256 + bSize[2] * 256*256 + bSize[3] * 256*256*256;
//將讀到的byte作運算
Label10->Caption=iFileSize;

fseek(fp,18,SEEK_SET);
fread(bSize, 1, 4, fp) ;
Label11->Caption=iFileWidth;

fseek(fp,22,SEEK_SET);
fread(bSize, 1, 4, fp) ;
FileHeight = bSize[0] + bSize[1] * 256 + bSize[2] * 256*256 + bSize[3] * 256*256*256;

fclose(fp); //關閉fopen

(上面只有部分程式碼,怕太多占版面)

HW3


1.程式原型
2.最後成果
利用fopen,fseek,fread等程式和bSize[0] +bSize[1] * 256 + bSize[2] * 256*256 + bSize[3] 再加上
bmp檔頭表就可以做出讀取bmp檔資料,一開始覺得很難但輟的過程中其實動作一直重複只是要注意每一個資料的byte數以免讀取錯誤,水平和垂直的解析度還需要再除39.37才能得到一公尺有多少bpi數 (dot per inch)








HW3



完成了這次的作業,這次的作業用到老師教的fopen開啟檔案,fseek指定
目標位置, fread將資料讀近來。所讀出的資料有圖片的格式、寬度、高
度、大小、解析度這些值, 其中解析度的值因要將公尺轉換成英吋,所以
要再將值除以39.37才為dpi值(dot per inch),老師上課所教的範例程式
是一個一個show出message,但這樣太繁瑣,所以用 Label->Caption
或列Memo讓他們看起來一目了然,這是老師今天上課一再提起的注意 事
項,做完了這次的做業也對fopen、fseek、fread有了更多的認知了,繼
續加油!

2009年11月5日 星期四

HW3


經過老師一堂課多的"自我檢討",我更能感受到老師認為我們的未來前途茫茫,不只是努力的教作業和應付考試而已,重點是要會"寫程式",說真的挺多老師說過主任也是,"只要會寫程式就很有用了",但是這"寫程式"的定義,是真的要會寫程式,不是寫寫簡單又小的程式,也不是頻頻和老師同學討論,更不是copypaste,以後在職場上通常都是要靠自己,要多利用身邊工具,網路、書籍等等,所以從現在開始我們就要習慣利用身邊各種資源,以後找資料就會更輕易上手,當然趁現在可以討論還是必要的。
這次交了fopen,fread,fseek,如果真的只看程式碼還真看不懂,而且fseek還需要位元組的位置才能找到檔案的資料,還有同學po了fopen,fread,fseek三個指令的說明,非常細心,也要感謝他讓我更了解一些,老師也幫我們解決了像素點的問題,單位要以公尺換公寸,所以100/2.54約等於39.37,所以就再除以39.37就正確了,現在還有個問題,cbuffer會出現亂碼,還有有些BMP檔的解析度會為0,感覺還是有很多問題待解決啊!

HW3















ACDsee









小畫家













今天在課堂上就把作業給完成了
不過回家想交作業時卻發現一個問題
由於電腦裡沒有BMP格式的圖檔
所以我用看圖軟體ACDSee10來把JPG圖檔另存成BMP圖檔(第二張圖)
結果用程式讀取圖片時
發生水平解析度跟垂直解析度都為0的狀況
後來我想到我在學校將JPG圖檔轉換成BMP圖檔是用小畫家
所以改用小畫家來轉換
結果程式就有讀取的到水平解析度跟垂直解析度

一樣是BMP但卻會發生這樣的問題

HW3








這次作業用新的東西fopen & fread & fseek

bmp
檔 這次作業用到的表頭

起始位元組 所占位元組數 具體內容 標識

1 2 檔案類型(windows點陣圖為“BM”)bfType

3 4 文件大小 bfSize

19 4 點陣圖的寬度 biWidth

23 4 點陣圖的高度 biHeight

39 4 點陣圖水準分辯率(像素/米) biXPelsPerMeter

43 4 點陣圖垂直分辯率(像素/米) biYPelsPerMeter



擷取檔案格式
imBMP = fopen(OpenPictureDialog1->FileName.c_str(), "r")

擷取檔案大小
fread(bSize, 1, 4, imBMP)

擷取檔案寬度
fseek(imBMP,18,SEEK_SET)

擷取檔案長度
fseek(imBMP,22,SEEK_SET)

擷取水平解析度
fseek(imBMP,38,SEEK_SET)

擷取垂直解析度
fseek(imBMP,42,SEEK_SET)


使用fseek可以直接抓取Bitmap File Header裡面你想要項目,不用像fread要抓取前面的空間不用的空間,但是抓取出的值會是 (像素/公尺)所以要除上39.37才會變成英吋!