C++ /檔案流 /BMP檔案讀寫
阿新 • • 發佈:2018-12-30
把一個字元寫到輸出流中:
從磁碟檔案讀取資料。
補充: OpenGL提供了簡潔的函式來操作畫素:
glReadPixels:讀取一些畫素。當前可以簡單理解為“把已經繪製好的畫素(它可能已經被儲存到顯示卡的視訊記憶體中)讀取到記憶體”。
glDrawPixels:繪製一些畫素。當前可以簡單理解為“把記憶體中一些資料作為畫素資料,進行繪製”。
glCopyPixels:複製一些畫素。當前可以簡單理解為“把已經繪製好的畫素從一個位置複製到另一個位置”。雖然從功能上看,好象等價於先讀取畫素再繪製畫素,但實際上它不需要把已經繪製的畫素(它可能已經被儲存到顯示卡的視訊記憶體中)轉換為記憶體資料,然後再由記憶體資料進行重新的繪製,所以要比先讀取後繪製快很多。
cout.put('c'); // 輸出一個字元
cout<<'c'; // 輸出一個字元,但是此前設定的寬度和填充方式在此起作用
write 函式:
把記憶體中的一塊兒內容寫到一個輸出檔案中,該函式有兩個引數:一個char指標(指向記憶體資料的起始地址)和一個所寫位元組數。常用於二進位制檔案的輸出。(\(^o^)/~這個很有用哦) 注意:當用write 函式輸出資料時,如果檔案是按照binary模式開啟,寫到檔案的資料和輸出的資料完全相同。但是,如果檔案是按照文字模式開啟的,當輸出整數10,即二進位制數00001010 時,系統會認為它是ASCII字元回車,並且自動加上一個ASCII 字元00001101 ,也就是換行。變為將”回車換行“輸出到檔案。所以,用write 函式輸出資料時,檔案應該按照binary模式開啟。seekp 和 tellp 函式:
seekp 把位置指標設定到某位置,tellp返回當前指標位置。(可參考下面的程式1)close 函式:
與open 相對應,把輸出檔案流關聯的磁碟檔案關閉。一般來講,輸出流解構函式會自動關閉流關聯的檔案,不必顯示呼叫,但是如果要在同一個流物件上開啟另外的檔案,就需要close 函式。 ================================================================================================================================檔案輸入流:
read 函式:
從一個檔案 把位元組流讀到一個指定的儲存區,當讀了指定的位元組數或者遇到檔案結束符時讀結束。seekg 和 tellg 函式:
在輸入檔案流中,儲存著一個指向下一個將要讀取資料的位置的內部指標,可以用seekg來設定這個指標。 tellg 返回當前檔案讀指標的位置,這個值是streampos型別,定義在iostream.h檔案中。 ==================================================================================================================================幾個栗子:
1、指標定位,檔案長度獲取,檔案讀寫
// -----------------------------------------------------------------------------------------
// Function:讀取一個視訊檔案,然後將該視訊檔案另存為。
// -----------------------------------------------------------------------------------------
#include<iostream>
#include <fstream>
const int LENGTH = 32*1024;
using namespace std;
void main()
{
char buff[LENGTH];
streamoff curpos;
streamoff endpos;
streamoff length;
int flag =1;
int count=0;
ifstream srcfile("1.avi",ios::binary);
ofstream destfile("11.avi",ios::binary|ios::app);
while(flag)
{
curpos=srcfile.tellg();// 獲取當前讀指標位置 // 成功才會是正常值,否則是-1
srcfile.seekg(0,ios::end);// 將讀指標放置於檔案末尾
endpos=srcfile.tellg();
length=endpos-curpos;
srcfile.seekg(curpos);// 恢復當前讀指標
if (length>=LENGTH)
{
srcfile.read(buff,LENGTH );
destfile.write(buff,LENGTH);// 前面說過,使用write時,需要用binary模式開啟。
count+=LENGTH/1024;
cout<<"本次傳送:"<<LENGTH/1024<<" KB ; "<<"總髮送:"<<count<<" KB "<<endl;
}
else
{
srcfile.read(buff,length);
destfile.write(buff,length);
count+=length/1024;
cout<<"本次傳送:"<<length/1024<<" KB ; "<<"總髮送:"<<count<<" KB "<<endl;
flag=0;
}
}
char wbp=getchar();
}
2、變數寫入檔案,檔案資料排版
//----------------------------------------------------------------------------------------------------------------------
// Function: 建立一個大陣列,寫入資料,然後存到磁碟檔案;將磁碟檔案資料讀入到大陣列中。
//----------------------------------------------------------------------------------------------------------------------
#include <iostream>
#include <fstream>
using namespace std;
struct Point2f
{
float x;
float y;
};
struct Point2fv
{
float x;
float y;
};
Point2fv PicAndPoint[6][4];
Point2fv testP[6][4];
void main()
{
for (int i=0;i<3;++i)
{
for (int j=0;j<2;++j)
{
PicAndPoint[2*i+j][0].x= -1+j;
PicAndPoint[2*i+j][0].y= 1/3.0-i*2/3.0;
PicAndPoint[2*i+j][1].x=0+j;
PicAndPoint[2*i+j][1].y=1/3.0-i*2/3.0;
PicAndPoint[2*i+j][2].x=0+j;
PicAndPoint[2*i+j][2].y=1-i*2/3.0;
PicAndPoint[2*i+j][3].x= -1+j;
PicAndPoint[2*i+j][3].y=1-i*2/3.0;
}
}
ofstream destfile("F:\\conversion.txt", ios::app);
for (int i=0;i<6;++i)
{
for (int j=0;j<4;++j)
{
destfile<<PicAndPoint[i][j].x<<" "<<PicAndPoint[i][j].y<<"\n"; // 此處有回車符
}
}
destfile.close();
ifstream srctfile("F:\\conversion.txt", ios::in);
for (int i=0;i<6;++i)
{
for (int j=0;j<4;++j)
{
srctfile>>testP[i][j].x>>testP[i][j].y; // 忽略了回車符
}
}
srctfile.close();
}
3、點陣圖檔案(BMP)的儲存
截圖神馬的可以參考這裡的程式碼。 用到#include <gl.h> #include <glut.h>void saveSceneImage(int x,int y,int width, int height)
{
//glGetIntegerv(GL_VIEWPORT,ViewPort);
int ColorChannel = 3; // 點陣圖檔案通道數,RGB
int bufferSize = width*height*sizeof(GLubyte)*ColorChannel;
char * ImgData = new char[bufferSize];
// OpenGL 相關
glPixelStorei(GL_UNPACK_ALIGNMENT,4); // 4位元組對齊
glReadPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE,ImgData); //從影象快取裡讀取一塊資料到記憶體
BITMAPFILEHEADER hdr;
BITMAPINFOHEADER infoHdr;
// 我們只需要關心點陣圖的尺寸,其他值預設就好了
infoHdr.biSize = sizeof(BITMAPINFOHEADER);
infoHdr.biWidth =width;
infoHdr.biHeight = height;
infoHdr.biPlanes = 1;
infoHdr.biBitCount = 24;
infoHdr.biCompression = 0;
infoHdr.biSizeImage =width*height*3;
infoHdr.biXPelsPerMeter = 0;
infoHdr.biYPelsPerMeter = 0;
infoHdr.biClrUsed = 0;
infoHdr.biClrImportant = 0;
hdr.bfType = 0x4D42;
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = 54;
hdr.bfSize =(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+width* height * 3);
ofstream destfile("F:\\snap.bmp",ios::binary | ios::app);// app模式,依次寫入BITMAPFILEHEADER、BITMAPINFOHEADER和影象資料
destfile.write((char*)&hdr,sizeof(BITMAPFILEHEADER));
//destfile.seekp(sizeof(BITMAPFILEHEADER));
destfile.write((char*)&infoHdr,sizeof(BITMAPINFOHEADER));
//destfile.seekp(sizeof(BITMAPINFOHEADER));
destfile.write((char*)ImgData,width* height * 3);
delete[] ImgData;
}
補充: OpenGL提供了簡潔的函式來操作畫素:
glReadPixels:讀取一些畫素。當前可以簡單理解為“把已經繪製好的畫素(它可能已經被儲存到顯示卡的視訊記憶體中)讀取到記憶體”。
glDrawPixels:繪製一些畫素。當前可以簡單理解為“把記憶體中一些資料作為畫素資料,進行繪製”。
glCopyPixels:複製一些畫素。當前可以簡單理解為“把已經繪製好的畫素從一個位置複製到另一個位置”。雖然從功能上看,好象等價於先讀取畫素再繪製畫素,但實際上它不需要把已經繪製的畫素(它可能已經被儲存到顯示卡的視訊記憶體中)轉換為記憶體資料,然後再由記憶體資料進行重新的繪製,所以要比先讀取後繪製快很多。