底下 code 僅用以呈現初始算法概念,由於 GetPixel、SetPixel 速度極慢,
實際上處理時會 LockBits 直接修改 raw pixels。
#pragma comment (lib, "gdiplus.lib") #include <windows.h> #include <stdio.h> #include <gdiplus.h> #define ex_by_daviddr 97 extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow(); using namespace Gdiplus; typedef unsigned char Byte; typedef int PixelType; void setSize (int w=1000, int h=800) { HANDLE hOut = GetStdHandle (STD_OUTPUT_HANDLE); SMALL_RECT rc = {0, 0, w/8 ,h/16}; COORD size = {w/8+1 ,h/16+1}; SetConsoleScreenBufferSize (hOut, size); SetConsoleWindowInfo (hOut, 1,&rc); } struct GDIp { GdiplusStartupInput in; ULONG_PTR tok; GDIp() {GdiplusStartup (&tok, &in, 0);} ~GDIp() {GdiplusShutdown (tok);} } GDIp; template <typename T, PixelFormat fmt> void scale ( Bitmap& const in, Bitmap& out, float sx, float sy) { Color c1, c2, c3, c4; int x, y, r,g,b, iw = in.GetWidth(), w = iw*sx, ih = in.GetHeight(), h = ih*sy; float dx = float(iw)/w, dy = float(ih)/h, ix, iy, s,t, p1,p2,p3,p4; for (y=0; y<h; ++y) for (x=0; x<w; ++x) { ix = dx*x; s = ix - int(ix); iy = dy*y; t = iy - int(iy); in.GetPixel (ix, iy, &c1); p1 = (1-s)*(1-t); in.GetPixel (ix, iy+1,&c2); p2 = (1-s)*t; in.GetPixel (ix+1,iy, &c3); p3 = s*(1-t); in.GetPixel (ix+1,iy+1,&c4); p4 = s*t; r = c1.GetR()*p1+ c2.GetR()*p2+ c3.GetR()*p3+ c4.GetR()*p4; g = c1.GetG()*p1+ c2.GetG()*p2+ c3.GetG()*p3+ c4.GetG()*p4; b = c1.GetB()*p1+ c2.GetB()*p2+ c3.GetB()*p3+ c4.GetB()*p4; out.SetPixel (x,y, Color(r,g,b)); } } int main() { setSize(); Graphics gp (GetDC (GetConsoleWindow())); gp.SetInterpolationMode (InterpolationModeHighQualityBicubic); Bitmap in (L"d:/img.jpg"); Bitmap out (800, 600); //畫布 scale <PixelType, PixelFormat32bppRGB> (in, out, 1.0/2, 2); gp.DrawImage (&in, 0,0); gp.DrawImage (&out, in.GetWidth(), 0); return getchar(); }
沒有留言:
張貼留言