自從最初發布以來,有些事情已發生更改。我用編輯標題標記它們。使用fwrite()編寫某些字節時出錯
我正在用不同格式的源代碼編寫圖像文件。這是1024x1024數據,每個像素有2個字節。
源圖像和目標圖像格式都包含可變數量字節的頭(包含元數據,如每像素的字節等),然後是圖像數據。
不知道是否相關,但我們使用了40多年前的軟件(稱爲Mcidas)來顯示這些圖像 以前,我將兩個字節讀入unsigned short
陣列。然後將它們連接到一個新的unsigned short
。然後我使用fwrite()
函數將它們寫入目標文件。
編輯
我現在就data
使用fread()
直接。
讀操作工作良好(嘗試都fputc()
和fread()
)兩個文件完全匹配的hexdumps的
編輯
的圖像數據部分。但是,由於某些原因,圖像似乎在某些字節中顯示有點錯誤。源文件似乎也很乾淨。
這裏的圖片(2MB的文件):
http://pdsimage.wr.usgs.gov/archive/mess-e_v_h-mdis-2-edr-rawdata-v1.0/MSGRMDS_1001/DATA/2007_156/EW0089565661F.IMG
你可以這樣保存爲 「source.IMG」 進行測試。
以下是源圖像和最終圖像的比較,在第一行上進行了行掃描。
Source file and Image http://i60.tinypic.com/11j24cy.png
注意突然跳躍某些像素,即產生輪廓。這些長度似乎大約爲256,這導致我們懷疑某處可能會出現翻轉位(標誌位可能?)。然而,相同的六角形表示不然。
下面是錯誤的代碼:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
unsigned char data_arr[2];
unsigned short data;
data=0;
int pixel_per_line=1024;
char path1[80]="source.IMG";
char path[80]="destination"
fp=fopen(path1,"rb");
bin=fopen(path,"wb");
//fp points to the input file, bin to the output file.
fseek(fp,8193,SEEK_SET);//sets the pointer to the relevant byte in the source file.
//A similar fseek() is used on bin in the original program
while(!feof(fp))
{
//fflush(fp); (Removed the fflush()s now)
int j;
for(j=0;j<pixels_per_line;j++)//iterate through all pixels in one line
{
for(int i=0;i<2;i++)
data_arr[i]=fgetc(fp);
//data=(data_arr[0] << 8) | data_arr[1];// bit manipulations done in the earlier version.
//This fails to give the right output.
data=data_arr[0]*256 + data_arr[1]; // This switches alternate bytes.
if(fwrite(&data,1,sizeof(data),bin)!=2)
printf("Write pains!");
}
//fflush(bin);
}
}
編輯:
添加了
fopen()
報表,並與fflush()
去除測試,錯誤依舊。新增聲明
unsigned short data
代碼應立即運行。
編輯
問題解決了2個字節的圖像! 我所做的只是切換備用字節。看看更正的代碼。 我不確定它爲什麼可以工作。這是一個排序問題嗎?請注意,位移不起作用。
我現在對四字節圖像有類似的問題。數據存儲爲浮點數。 I fread()
將這些字節轉換爲一個浮點數,對其進行縮放並將其轉換爲整數。結果同樣有顆粒感。用bitshifts排列字節不能解決問題。
任何人都可以對此有所瞭解嗎?
'fflush(fp);'是未定義的行爲,您需要先解決類似的問題,然後才能指望任何工作。顯示你如何打開你的文件。 –
'fwrite(&data,1,2,bin)'你有一個不必要的幻數。最好使用'fwrite(&data,1,sizeof(data),bin)'。這是一個小的細節,但它明確地向讀者顯示,您不會因誤解尺寸而忽略覆蓋,並且在將來會提高可維護性。 – dmckee
while(!feof(fp))'不符合你的想法。直到'fgetc()'已經失敗一次,它纔會返回true。 –