與其花時間找,不如自己寫一段比較快。
點陣圖的資料,是每 1 個 bit 代表 1 個點,1 個 byte 8 個點,左上角為第一個點。
這裡的放大構想是這樣,
for (int i = 0; i < pixel_height; i++) { if need scale on the x-axis // scale one line else // copy one line if need scale on the y-axis // copy line }
如上所示,FOR LOOP 為原始圖片的高度,動作流程如下,
- 先判斷橫向 X 座標的放大倍率,需放大時放大,
- 不需要時只複製一行的大小。
- 再判斷縱向Y座標的放大倍率,需放大時利用已經完成的第一行來放大,不需要時維持原來的即可。
需要的單行放大函數功能是這樣:
void line_scale(unsigned char *sour, unsigned int w_byte, unsigned char *dest, unsigned int magnification)
依序說明如下,
sour: 點陣圖的資料來源(by address),
w_byte: 圖片的寬占用幾個 Byte,
dest: 放大後的圖片資料空間(by address),
magnification: 放大倍率。
完整的原始碼如下:
void line_scale(unsigned char *sour, unsigned int w_byte, unsigned char *dest, unsigned int magnification) { unsigned int i = 0; unsigned int k = 0; unsigned char cc = 0; unsigned char bit_mask = 0; unsigned char one_bit = 0; unsigned char bit_write_mask = 0; if (sour == 0 || dest == 0 || w_byte == 0 || magnification <= 1) return; bit_write_mask = 0x80; // set to first bit for (i = 0; i < w_byte; i++) { cc = sour[i]; // get one byte data for (bit_mask = 0x80; bit_mask > 0; bit_mask >>= 1) { one_bit = cc & bit_mask; // get one bit data for (k = 0; k < magnification; k++) { if (one_bit) *dest |= bit_write_mask; // set else *dest &= ~bit_write_mask; // clear bit_write_mask >>= 1; // right shift bit for next bit if (bit_write_mask == 0) { dest++; // to next byte bit_write_mask = 0x80; // set to first bit } } } } }
後續:
這個方法只支援輸入圖片寬所佔的 Byte 數,所以寬度一定為 8 的倍數。對於非 8 的倍數的圖片,似乎沒這麼好用,即使將原始資料的右邊位元設為 0,意即圖片資料靠左位元,這樣的方式也花費了一些時間來處理非圖片資料的位元。這是個可以改進的地方,但是這範例已經足夠完成工作項目,所以就先不修改了。
就是醬
沒有留言:
張貼留言