搞過計算機圖像的人都知道,圖像中的每一個像素通常為一個整型數,它可以分成4個無符號的char類型,以表示其RGBA四個分量。一幅圖像可以看做是一個二維整型數組。這里我會生成一個float數組,其數組大小為1000000,剛好1000*1000,數組內的浮點數的數值范圍在0到1000.0之間,呈等差數組排列,相鄰兩數的差為0.001。然后將其每一個浮點數強制轉化成一個整型數或三個unsigned char型,以決定像素的RGB三個通道分量,看看其生成的圖像是什么樣子。
前幾天寫了一篇文章是在C語言中使用異或運算交換兩個任意類型變量,引來某人的質疑,說什么“指針的強制類型轉換有一定限制,不是你想怎么轉就怎么轉的,結果可能會出錯的”。用這種莫須有的話來否定我的代碼。為嘲笑他的無知,我特意寫出這種用強制指針類型轉換生成圖像的算法。
先上C代碼:
#include <iostream> #include <cmath> #include <cstdlib>
#define DIM 1000
void pixel_write(int,int); FILE *fp; int main() { fp = fopen("image.ppm","wb"); if (!fp) { return -1; } fprintf(fp, "P6\n%d %d\n255\n", DIM, DIM); for(int j=0;j<DIM;j++) { for(int i=0;i<DIM;i++) { pixel_write(i,j); } } fclose(fp); return 0; } void pixel_write(int i, int j) { static unsigned char color[3]; float t = j + i*0.001f; memcpy(color, &t, 3); fwrite(color, 1, 3, fp);
// 其實更簡單粗爆的方式是
//fwrite(&t, 1, 3, fp);
}
代碼運行后會生成一種PPM格式的圖像,如下圖所示:
圖像多少有點分形的感覺。PPM格式的圖像不太常見,它是一種非常簡單的圖像格式。在我寫的軟件Why數學圖像生成工具中可以查看,當然我也將該圖像的生成算法寫到這個軟件中,相關代碼如下:
#ifndef _PixelFloatConvertInt_H_ #define _PixelFloatConvertInt_H_
// --------------------------------------------------------------------------------------
#include "IPixelEquation.h"
// --------------------------------------------------------------------------------------
class CPixelFloatConvertInt : public IPixelEquation { public: CPixelFloatConvertInt() { m_width = 1000; m_height = 1000; } const char* GetName() const { return "Float Convert Int"; } unsigned int CalculatePixel(unsigned int x, unsigned int y) { float t = y + x*0.001f; unsigned int rst = *(unsigned int*)&t; rst |= 0xff000000; return rst; } }; // --------------------------------------------------------------------------------------
#endif
使用Why數學圖像生成工具可以查看該圖像的紅綠藍三個分量:
R通道圖:
G通道圖:
B通道圖:
代碼稍做修改,分形效果更為明顯:
unsigned int CalculatePixel(unsigned int x, unsigned int y) { float t = y/4+ x*0.001f; unsigned int rst = *(unsigned int*)&t; rst |= 0xff000000; return rst; }