因工作需要『放大單色點陣圖』的功能,原本想上網找了一下直接引用,但發現不好找。
與其花時間找,不如自己寫一段比較快。
點陣圖的資料,是每 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,意即圖片資料靠左位元,這樣的方式也花費了一些時間來處理非圖片資料的位元。這是個可以改進的地方,但是這範例已經足夠完成工作項目,所以就先不修改了。
就是醬