2009年11月23日 星期一

用Ansi C寫一個很蠢的影像壓縮程式...

在PTT的某板上看到有人發了關於影像壓縮的求救文,
基於好心所以推文給點建議,
然後就丟水球來啦~
原來是作業,啥都不要求,
只要求影像壓縮= =,壓縮大小為原先的一半...

因為無聊所以隨便寫了一個給他...
因為懶...所以直接在機器上面寫...
所以先找了個人家寫好的來改...
(原創) 如何使用Standard Library作影像處理? (C/C++) (Image Processing)
大陸那邊的東西,天知道到底是誰原創...
因為愛...所以就不拉library來用...
(實際上是嫌GD跟eazybmp太複雜...我只要讀檔案跟寫檔案而已)

就撈了人家的code過來,拿現成的來改...
讀取跟寫入Bitmap的Header的函式已經寫好了...
只是隔天就在C_and_CPP板上看到有人說這個寫法很爛還被抄來抄去...
完全不考慮Endianness的土炮寫法,
管他媽媽嫁給誰,能用就先不管了,反正不是我的作業...XDDDD

用了一個很爛的作法,
把每個byte的低4位元拿掉,然後把2個bytes合成1個byte,
這樣可以節省一半的空間,但是圖片還原不至於差的太多。
其實這是之前上課提到一個很無聊的東西,一張圖A隱藏在另一張圖B當中,
平常看是圖B,但是當圖片反白的時候看起來就是圖A了...
原理是差不多的XDDDD

寫了兩個Function...

int enc(unsigned char *ori, unsigned char *tar, int xsize, int ysize) {
int x;
int y;

for(y = 0; y != ysize; ++y) {
for(x = 0; x != xsize; ++x) {
if (x % 2 == 0){
*(tar + 3 * (y * xsize + (int)(x/2)) + 2) = *(ori + 3 * (y * xsize + x) + 2) & 240;
*(tar + 3 * (y * xsize + (int)(x/2)) + 1) = *(ori + 3 * (y * xsize + x) + 1) & 240;
*(tar + 3 * (y * xsize + (int)(x/2)) + 0) = *(ori + 3 * (y * xsize + x) + 0) & 240;
}
else{
*(tar + 3 * (y * xsize + (int)(x/2)) + 2) = *(tar + 3 * (y * xsize + (x/2)) + 2) | (*(ori + 3 * (y * xsize + x) + 2) & 240) >> 4;
*(tar + 3 * (y * xsize + (int)(x/2)) + 1) = *(tar + 3 * (y * xsize + (x/2)) + 1) | (*(ori + 3 * (y * xsize + x) + 1) & 240) >> 4;
*(tar + 3 * (y * xsize + (int)(x/2)) + 0) = *(tar + 3 * (y * xsize + (x/2)) + 0) | (*(ori + 3 * (y * xsize + x) + 0) & 240) >> 4;
}
}
}

return 0;
}



int dec(unsigned char *ori, unsigned char *tar, int xsize, int ysize) {
int x;
int y;

for(y = 0; y != ysize; ++y) {
for(x = 0; x != xsize; ++x) {
if (x % 2 == 0){
*(tar + 3 * (y * xsize + x) + 2) = *(ori + 3 * (y * xsize + (int)(x/2)) + 2) & 240;
*(tar + 3 * (y * xsize + x) + 1) = *(ori + 3 * (y * xsize + (int)(x/2)) + 1) & 240;
*(tar + 3 * (y * xsize + x) + 0) = *(ori + 3 * (y * xsize + (int)(x/2)) + 0) & 240;
}
else{
*(tar + 3 * (y * xsize + x) + 2) = (*(ori + 3 * (y * xsize + (int)(x/2)) + 2) & 15) << 4;
*(tar + 3 * (y * xsize + x) + 1) = (*(ori + 3 * (y * xsize + (int)(x/2)) + 1) & 15) << 4;
*(tar + 3 * (y * xsize + x) + 0) = (*(ori + 3 * (y * xsize + (int)(x/2)) + 0) & 15) << 4;
}
}
}

return 0;
}


然後很好心的順便算了一下PSNR...
用Lena 512x512的圖來跑,PSNR還有8左右的水準...
看的出少掉一些細節,不過也算壓縮了不是?
只是真的很蠢...
蠢到八成不會有人會想寫這種東西放在網路上給人家抓...

完整的code...
20091123_image_compress

結論咧?那位苦主八成連拿來修一修都有困難...
直接跟老師說明年再見吧...

沒有留言:

張貼留言

How to disable GUI on armbian (revert the Desktop to server)

Check which Display manager that you're using currently cat /etc/X11/default-display-manager nodm should be default if you're choose...