├── ResizeImage ├── ResizeImage.cpp ├── ResizeImage.h ├── ResizeImage.sln ├── ResizeImage.vcxproj └── ResizeImage.vcxproj.filters └── TestResizeImage ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── TestResizeImage.csproj └── icon.jpg /ResizeImage/ResizeImage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "ResizeImage.h" 6 | 7 | #define CAP(x) ((x) < 0.0f ? 0.0f : (x) > 1.0f ? 1.0f : (x)) 8 | #define ROUND(x) (floor(x + 0.5)) 9 | 10 | const int LANCZOS_WINDOW = 2; 11 | const float LANCZOS_BLUR = 1.25; 12 | const int GAMMASIZE = 200000; 13 | 14 | int maxUpscale = 100; 15 | 16 | #pragma region Exported methods 17 | 18 | void SetMaximumUpscale(int percentage) 19 | { 20 | maxUpscale = percentage; 21 | } 22 | 23 | BITMAPINFOHEADER __declspec(dllexport) GetResizedImageInfo(int width, int height, int maxwidth, int maxheight) 24 | { 25 | return CResizeImage(width, height, maxwidth, maxheight).DetermineNewSize(); 26 | } 27 | 28 | void __declspec(dllexport) ResizeImage(unsigned char *buffer, BITMAPINFOHEADER bminfo, unsigned char *newbuffer, BITMAPINFOHEADER newbminfo) 29 | { 30 | CResizeImage(buffer, bminfo, newbuffer, newbminfo).Resize(); 31 | } 32 | 33 | #pragma endregion 34 | 35 | #pragma region CResizeImage implemetation 36 | 37 | #pragma region Constructors 38 | 39 | CResizeImage::CResizeImage(int width, int height, int maxwidth, int maxheight) 40 | : width(width), height(height), maxwidth(maxwidth), maxheight(maxheight) 41 | { 42 | InitGamma(); 43 | } 44 | 45 | CResizeImage::CResizeImage(unsigned char *buffer, BITMAPINFOHEADER bminfo, unsigned char *newbuffer, BITMAPINFOHEADER newbminfo) 46 | : buffer(buffer), bminfo(bminfo), newbuffer(newbuffer), newbminfo(newbminfo) 47 | { 48 | width = bminfo.biWidth; 49 | height = bminfo.biHeight; 50 | newwidth = newbminfo.biWidth; 51 | newheight = newbminfo.biHeight; 52 | bpp = bminfo.biBitCount >> 3; 53 | newbpp = newbminfo.biBitCount >> 3; 54 | 55 | InitGamma(); 56 | } 57 | 58 | #pragma endregion 59 | 60 | #pragma region Public methods 61 | 62 | BITMAPINFOHEADER CResizeImage::DetermineNewSize(void) 63 | { 64 | fx = (float)maxwidth / width; 65 | fy = (float)maxheight / height; 66 | 67 | if (width < maxwidth && height < maxheight && maxUpscale > 100) 68 | { 69 | float upscale = (float)maxUpscale / 100; 70 | 71 | if (fx < fy) 72 | { 73 | fx = fx > upscale ? upscale : fx; 74 | fy = fx; 75 | } 76 | else 77 | { 78 | fy = fy > upscale ? upscale : fy; 79 | fx = fy; 80 | } 81 | } 82 | else if (width > maxwidth || height > maxheight) 83 | { 84 | if (fx < fy) 85 | fy = fx; 86 | else 87 | fx = fy; 88 | } 89 | else 90 | { 91 | fx = 1.0f; 92 | fy = 1.0f; 93 | } 94 | 95 | newbminfo.biWidth = ROUND(fx * width); 96 | newbminfo.biHeight = ROUND(fy * height); 97 | 98 | return newbminfo; 99 | } 100 | 101 | void CResizeImage::Resize(void) 102 | { 103 | fx = (float)width / newwidth; 104 | fy = (float)height / newheight; 105 | 106 | rowsize = CalculateRowSize(bpp, width); 107 | newrowsize = CalculateRowSize(newbpp, newwidth); 108 | 109 | if (fx > 1.0 || fy > 1.0) 110 | ScaleDown(); 111 | else 112 | ScaleUp(); 113 | } 114 | 115 | #pragma endregion 116 | 117 | #pragma region Scaling implementation 118 | 119 | void CResizeImage::ScaleDown(void) 120 | { 121 | int nrrows = (int)ceil(fy + 1.0f); 122 | unsigned char **rows = new unsigned char *[nrrows]; 123 | float *dxA, *dxB, *dyA = new float[nrrows]; 124 | int *ixA, *iyA = new int[nrrows], *nrxA; 125 | unsigned char *newline = newbuffer, *c1, *c2; 126 | float starty, endy = 0.0f, dy, diffY; 127 | int pos, nrx, nrx1, nry, t3, t6; 128 | float sum1, sum2, sum3, f, area; 129 | 130 | ScaleDownPreCalculate(ixA, dxA, nrxA, dxB); 131 | 132 | for (int t1 = 0; t1 < newheight; t1++) 133 | { 134 | pos = t1 * fy; 135 | t3 = pos + nrrows < height + 1 ? 0 : pos - height + 1; 136 | 137 | for (int t2 = 0; t2 < nrrows + t3; t2++) 138 | { 139 | rows[t2] = buffer + (pos + t2) * rowsize; 140 | } 141 | 142 | starty = t1 * fy - pos; 143 | endy = (t1 + 1) * fy - pos + t3; 144 | diffY = endy - starty; 145 | nry = 0; 146 | 147 | for (float y = starty; y < endy; y = floor(y + 1.0f)) 148 | { 149 | iyA[nry] = (int)y; 150 | if (endy - y > 1.0f) 151 | dyA[nry] = floor(y + 1.0f) - y; 152 | else 153 | dyA[nry] = endy - y; 154 | 155 | nry++; 156 | } 157 | 158 | nrx = 0; 159 | t6 = 0; 160 | 161 | for (int t2 = 0; t2 < newwidth; t2++) 162 | { 163 | t3 = nrxA[t2]; 164 | area = (1.0f / (dxB[t2] * diffY)) * GAMMASIZE; 165 | sum1 = sum2 = sum3 = 0.0f; 166 | 167 | for (int t4 = 0; t4 < nry; t4++) 168 | { 169 | c1 = rows[iyA[t4]]; 170 | dy = dyA[t4]; 171 | 172 | nrx1 = nrx; 173 | 174 | for (int t5 = 0; t5 < t3; t5++) 175 | { 176 | f = dxA[nrx1] * dy; 177 | c2 = c1 + ixA[nrx1]; 178 | 179 | sum1 += togamma[c2[0]] * f; 180 | sum2 += togamma[c2[1]] * f; 181 | sum3 += togamma[c2[2]] * f; 182 | 183 | nrx1++; 184 | } 185 | } 186 | 187 | newline[t6 + 0] = fromgamma[(int)(sum1 * area)]; 188 | newline[t6 + 1] = fromgamma[(int)(sum2 * area)]; 189 | newline[t6 + 2] = fromgamma[(int)(sum3 * area)]; 190 | 191 | nrx += t3; 192 | t6 += newbpp; 193 | } 194 | 195 | newline += newrowsize; 196 | } 197 | 198 | delete rows; 199 | delete nrxA; 200 | delete ixA; 201 | delete iyA; 202 | delete dxA; 203 | delete dyA; 204 | delete dxB; 205 | } 206 | 207 | void CResizeImage::ScaleDownPreCalculate(int* &ixA, float* &dxA, int* &nrxA, float* &dxB) 208 | { 209 | int nrcols = (int)ceil(fx + 1.0f); 210 | int nrx = 0, nrx1; 211 | float startx = 0.0f; 212 | float endx = fx; 213 | 214 | dxA = new float[nrcols * newwidth]; 215 | dxB = new float[newwidth]; 216 | ixA = new int[nrcols * newwidth]; 217 | nrxA = new int[newwidth]; 218 | 219 | for (int t1 = 0; t1 < newwidth; t1++) 220 | { 221 | endx = endx < width + 1 ? endx : endx - width + 1; 222 | 223 | for (float x = startx; x < endx; x = floor(x + 1.0f)) 224 | { 225 | ixA[nrx] = (int)x * bpp; 226 | 227 | if (endx - x > 1.0f) 228 | dxA[nrx] = floor(x + 1.0f) - x; 229 | else 230 | dxA[nrx] = endx - x; 231 | 232 | nrx++; 233 | } 234 | 235 | if (t1 > 0) 236 | nrxA[t1] = nrx - nrx1; 237 | else 238 | nrxA[t1] = nrx; 239 | 240 | nrx1 = nrx; 241 | 242 | dxB[t1] = endx - startx; 243 | 244 | startx = endx; 245 | endx += fx; 246 | } 247 | } 248 | 249 | void CResizeImage::ScaleUp(void) 250 | { 251 | int *startx, *endx, *starty, *endy; 252 | float **hweights, **vweights; 253 | float *hdensity, *vdensity; 254 | float *vweight, *hweight; 255 | float sumh1, sumh2, sumh3, sumv1, sumv2, sumv3; 256 | 257 | ScaleUpPreCalculate(startx, endx, starty, endy, hweights, vweights, hdensity, vdensity); 258 | 259 | for (int t1 = 0; t1 < newheight; t1++) 260 | { 261 | int nmaxv = endy[t1] - starty[t1], nmaxh; 262 | unsigned char *line = newbuffer + t1 * newrowsize; 263 | 264 | for (int t2 = 0; t2 < newwidth; t2++) 265 | { 266 | nmaxh = endx[t2] - startx[t2]; 267 | unsigned char* ypos = buffer + starty[t1] * rowsize; 268 | 269 | sumv1 = sumv2 = sumv3 = 0.0f; 270 | vweight = vweights[t1]; 271 | 272 | for (int t3 = 0; t3 < nmaxv; t3++) 273 | { 274 | unsigned char *xpos = ypos + startx[t2] * bpp; 275 | 276 | sumh1 = sumh2 = sumh3 = 0.0f; 277 | hweight = hweights[t2]; 278 | 279 | for (int t4 = 0; t4 < nmaxh; t4++) 280 | { 281 | sumh1 += *hweight * togamma[xpos[0]]; 282 | sumh2 += *hweight * togamma[xpos[1]]; 283 | sumh3 += *hweight * togamma[xpos[2]]; 284 | 285 | xpos += bpp; 286 | hweight++; 287 | } 288 | 289 | sumv1 += *vweight * sumh1; 290 | sumv2 += *vweight * sumh2; 291 | sumv3 += *vweight * sumh3; 292 | 293 | ypos += rowsize; 294 | vweight++; 295 | } 296 | 297 | line[0] = fromgamma[(int)(CAP(sumv1) * GAMMASIZE)]; 298 | line[1] = fromgamma[(int)(CAP(sumv2) * GAMMASIZE)]; 299 | line[2] = fromgamma[(int)(CAP(sumv3) * GAMMASIZE)]; 300 | 301 | line += newbpp; 302 | } 303 | } 304 | 305 | delete startx; 306 | delete endx; 307 | delete starty; 308 | delete endy; 309 | for (int t1 = 0; t1 < newwidth; t1++) 310 | delete hweights[t1]; 311 | delete hweights; 312 | for (int t1 = 0; t1 < newheight; t1++) 313 | delete vweights[t1]; 314 | delete vweights; 315 | delete hdensity; 316 | delete vdensity; 317 | } 318 | 319 | void CResizeImage::ScaleUpPreCalculate( 320 | int* &startx, int* &endx, int* &starty, int* &endy, 321 | float** &hweights, float** &vweights, float* &hdensity, float* &vdensity) 322 | { 323 | float center, start, *vweight, *hweight; 324 | int nmax; 325 | 326 | startx = new int[newwidth]; 327 | endx = new int[newwidth]; 328 | starty = new int[newheight]; 329 | endy = new int[newheight]; 330 | hweights = new float*[newwidth]; 331 | vweights = new float*[newheight]; 332 | hdensity = new float[newwidth]; 333 | vdensity = new float[newheight]; 334 | 335 | // pre-calculation for each column 336 | for (int t1 = 0; t1 < newwidth; t1++) 337 | { 338 | center = ((float)t1 + 0.5f) * fx; 339 | 340 | startx[t1] = std::max(center - LANCZOS_WINDOW, 0), 341 | endx[t1] = std::min(ceil (center + LANCZOS_WINDOW), width - 1); 342 | nmax = endx[t1] - startx[t1]; 343 | start = (float)startx[t1] + 0.5f - center; 344 | 345 | hweights[t1] = new float[nmax]; 346 | hdensity[t1] = 0.0f; 347 | 348 | for (int t2 = 0; t2 < nmax; t2++) 349 | { 350 | hweights[t1][t2] = Lanczos((start + t2) / LANCZOS_BLUR); 351 | hdensity[t1] += hweights[t1][t2]; 352 | } 353 | 354 | for (int t2 = 0; t2 < nmax; t2++) 355 | hweights[t1][t2] /= hdensity[t1]; 356 | } 357 | 358 | // pre-calculation for each row 359 | for (int t1 = 0; t1 < newheight; t1++) 360 | { 361 | center = ((float)t1 + 0.5f) * fy; 362 | 363 | starty[t1] = std::max(center - LANCZOS_WINDOW, 0), 364 | endy[t1] = std::min(ceil (center + LANCZOS_WINDOW), height - 1); 365 | nmax = endy[t1] - starty[t1]; 366 | start = (float)starty[t1] + 0.5f - center; 367 | 368 | vweights[t1] = new float[nmax]; 369 | vdensity[t1] = 0.0f; 370 | 371 | for (int t2 = 0; t2 < nmax; t2++) 372 | { 373 | vweights[t1][t2] = Lanczos((start + t2) / LANCZOS_BLUR); 374 | vdensity[t1] += vweights[t1][t2]; 375 | } 376 | 377 | for (int t2 = 0; t2 < nmax; t2++) 378 | vweights[t1][t2] /= vdensity[t1]; 379 | } 380 | } 381 | 382 | #pragma endregion 383 | 384 | #pragma region Private methods 385 | 386 | int CResizeImage::CalculateRowSize(int bpp, int width) 387 | { 388 | int rowsize = bpp * width; 389 | 390 | return rowsize + ((rowsize % 4 > 0) ? 4 - (rowsize % 4) : 0); 391 | } 392 | 393 | float CResizeImage::Lanczos(float x) 394 | { 395 | if (x == 0.0f) 396 | return 1.0f; 397 | else 398 | { 399 | float xpi = x * 3.141593f; 400 | 401 | return LANCZOS_WINDOW * sin(xpi) * sin(xpi / LANCZOS_WINDOW) / (xpi * xpi); 402 | } 403 | } 404 | 405 | #pragma endregion 406 | 407 | #pragma region Static gamma members 408 | 409 | float *CResizeImage::togamma = NULL; 410 | unsigned char *CResizeImage::fromgamma = NULL; 411 | 412 | void CResizeImage::InitGamma(void) 413 | { 414 | if (togamma != NULL && fromgamma != NULL) 415 | return; 416 | 417 | togamma = new float[256]; 418 | 419 | for (int i1 = 0; i1 < 256; i1++) 420 | togamma[i1] = (float)pow(i1 / 255.0, 2.2); 421 | 422 | fromgamma = new unsigned char[GAMMASIZE + 50000]; 423 | 424 | for (int i2 = 0; i2 < GAMMASIZE + 1; i2++) 425 | fromgamma[i2] = (unsigned char)(pow((double)i2 / GAMMASIZE, 1 / 2.2) * 255); 426 | 427 | // In case of overflow 428 | for (int i3 = GAMMASIZE + 1; i3 < GAMMASIZE + 50000; i3++) 429 | fromgamma[i3] = 255; 430 | } 431 | 432 | #pragma endregion 433 | 434 | #pragma endregion 435 | -------------------------------------------------------------------------------- /ResizeImage/ResizeImage.h: -------------------------------------------------------------------------------- 1 | #ifndef __RESIZEIMAGE_H 2 | #define __RESIZEIMAGE_H 3 | 4 | #include 5 | 6 | extern "C" 7 | { 8 | void __declspec(dllexport) SetMaximumUpscale(int percentage); 9 | BITMAPINFOHEADER __declspec(dllexport) GetResizedImageInfo(int width, int height, int maxwidth, int maxheight); 10 | void __declspec(dllexport) ResizeImage(unsigned char *buffer, BITMAPINFOHEADER bminfo, unsigned char *newbuffer, BITMAPINFOHEADER newbminfo); 11 | }; 12 | 13 | class CResizeImage 14 | { 15 | public: 16 | 17 | CResizeImage(int width, int height, int maxwidth, int maxheight); 18 | CResizeImage(unsigned char *buffer, BITMAPINFOHEADER bminfo, unsigned char *newbuffer, BITMAPINFOHEADER newbminfo); 19 | 20 | BITMAPINFOHEADER DetermineNewSize(void); 21 | void Resize(void); 22 | 23 | private: 24 | 25 | int width, newwidth; 26 | int height, newheight; 27 | int bpp, newbpp; 28 | int maxwidth; 29 | int maxheight; 30 | 31 | float fx, fy; 32 | int rowsize, newrowsize; 33 | 34 | unsigned char *buffer; 35 | unsigned char *newbuffer; 36 | BITMAPINFOHEADER bminfo; 37 | BITMAPINFOHEADER newbminfo; 38 | 39 | void ScaleDown(void); 40 | void ScaleDownPreCalculate(int* &ixA, float* &dxA, int* &nrxA, float* &dxB); 41 | void ScaleUp(void); 42 | void ScaleUpPreCalculate( 43 | int* &startx, int* &endx, int* &starty, int* &endy, 44 | float** &hweights, float** &vweights, float* &hdensity, float* &vdensity); 45 | 46 | int CalculateRowSize(int bpp, int width); 47 | float Lanczos(float x); 48 | 49 | static float *togamma; 50 | static unsigned char *fromgamma; 51 | static void InitGamma(void); 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /ResizeImage/ResizeImage.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ResizeImage", "ResizeImage.vcxproj", "{A8523E91-E5C6-4532-A46B-0DF33EC102A0}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestResizeImage", "..\TestResizeImage\TestResizeImage.csproj", "{828EF737-BFC3-4980-B463-BACDE0EBEF91}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Mixed Platforms = Debug|Mixed Platforms 11 | Debug|Win32 = Debug|Win32 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|Mixed Platforms = Release|Mixed Platforms 15 | Release|Win32 = Release|Win32 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 21 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Debug|Mixed Platforms.Build.0 = Debug|x64 22 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Debug|Win32.ActiveCfg = Debug|Win32 23 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Debug|Win32.Build.0 = Debug|Win32 24 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Debug|x64.ActiveCfg = Debug|x64 25 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Debug|x64.Build.0 = Debug|x64 26 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Debug|x86.ActiveCfg = Debug|x64 27 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Release|Mixed Platforms.ActiveCfg = Release|x64 28 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Release|Mixed Platforms.Build.0 = Release|x64 29 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Release|Win32.ActiveCfg = Release|Win32 30 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Release|Win32.Build.0 = Release|Win32 31 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Release|x64.ActiveCfg = Release|x64 32 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Release|x64.Build.0 = Release|x64 33 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0}.Release|x86.ActiveCfg = Release|x64 34 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 35 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Debug|Mixed Platforms.Build.0 = Debug|x86 36 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Debug|Win32.ActiveCfg = Debug|x86 37 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Debug|x64.ActiveCfg = Debug|x86 38 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Debug|x86.ActiveCfg = Debug|x86 39 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Debug|x86.Build.0 = Debug|x86 40 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Release|Mixed Platforms.ActiveCfg = Release|x86 41 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Release|Mixed Platforms.Build.0 = Release|x86 42 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Release|Win32.ActiveCfg = Release|x86 43 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Release|x64.ActiveCfg = Release|x86 44 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Release|x86.ActiveCfg = Release|x86 45 | {828EF737-BFC3-4980-B463-BACDE0EBEF91}.Release|x86.Build.0 = Release|x86 46 | EndGlobalSection 47 | GlobalSection(SolutionProperties) = preSolution 48 | HideSolutionNode = FALSE 49 | EndGlobalSection 50 | EndGlobal 51 | -------------------------------------------------------------------------------- /ResizeImage/ResizeImage.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {A8523E91-E5C6-4532-A46B-0DF33EC102A0} 23 | Win32Proj 24 | ResizeImage 25 | 26 | 27 | 28 | DynamicLibrary 29 | true 30 | Unicode 31 | 32 | 33 | StaticLibrary 34 | false 35 | true 36 | Unicode 37 | 38 | 39 | DynamicLibrary 40 | 41 | 42 | DynamicLibrary 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | .dll 56 | 57 | 58 | .dll 59 | ..\TestResizeImage\bin\Debug 60 | 61 | 62 | .dll 63 | ..\TestResizeImage\bin\Release 64 | 65 | 66 | 67 | NotUsing 68 | Level3 69 | Disabled 70 | WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 71 | 72 | 73 | Windows 74 | true 75 | 76 | 77 | 78 | 79 | Level3 80 | Use 81 | MaxSpeed 82 | true 83 | true 84 | WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 85 | 86 | 87 | Windows 88 | true 89 | true 90 | true 91 | 92 | 93 | 94 | 95 | ProgramDatabase 96 | Disabled 97 | 98 | 99 | true 100 | true 101 | 102 | 103 | 104 | 105 | Speed 106 | false 107 | true 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /ResizeImage/ResizeImage.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Header Files 16 | 17 | 18 | 19 | 20 | Source Files 21 | 22 | 23 | -------------------------------------------------------------------------------- /TestResizeImage/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing.Imaging; 3 | using System.Runtime.InteropServices; 4 | using System.Drawing; 5 | 6 | namespace TestResizeImage 7 | { 8 | class Program 9 | { 10 | [StructLayout(LayoutKind.Sequential)] 11 | public struct BITMAPINFOHEADER 12 | { 13 | public uint biSize; 14 | public int biWidth; 15 | public int biHeight; 16 | public ushort biPlanes; 17 | public ushort biBitCount; 18 | public uint biCompression; 19 | public uint biSizeImage; 20 | public int biXPelsPerMeter; 21 | public int biYPelsPerMeter; 22 | public uint biClrUsed; 23 | public uint biClrImportant; 24 | } 25 | 26 | [DllImport("ResizeImage.dll", CallingConvention = CallingConvention.Cdecl)] 27 | public static extern void SetMaximumUpscale(int percentage); 28 | 29 | [DllImport("ResizeImage.dll", CallingConvention = CallingConvention.Cdecl)] 30 | public static extern BITMAPINFOHEADER GetResizedImageInfo(int width, int height, int maxwidth, int maxheight); 31 | 32 | [DllImport("ResizeImage.dll", CallingConvention = CallingConvention.Cdecl)] 33 | public static extern IntPtr ResizeImage(IntPtr buffer, BITMAPINFOHEADER bminfo, IntPtr newbuffer, BITMAPINFOHEADER newbminfo); 34 | 35 | static void Main() 36 | { 37 | SetMaximumUpscale(200); 38 | 39 | Bitmap imgsrc = new Bitmap("icon.jpg"); 40 | 41 | var infosrc = new BITMAPINFOHEADER 42 | { 43 | biWidth = imgsrc.Width, 44 | biHeight = imgsrc.Height, 45 | biBitCount = (ushort)Image.GetPixelFormatSize(imgsrc.PixelFormat) 46 | }; 47 | var infodest = GetResizedImageInfo(imgsrc.Width, imgsrc.Height, 1600, 1200); 48 | 49 | Rectangle recsrc = new Rectangle(0, 0, imgsrc.Width, imgsrc.Height); 50 | BitmapData datasrc = imgsrc.LockBits(recsrc, ImageLockMode.WriteOnly, imgsrc.PixelFormat); 51 | 52 | Bitmap imgdest = new Bitmap(infodest.biWidth, infodest.biHeight, PixelFormat.Format24bppRgb); 53 | Rectangle recdest = new Rectangle(0, 0, imgdest.Width, imgdest.Height); 54 | BitmapData datadest = imgdest.LockBits(recdest, ImageLockMode.WriteOnly, imgdest.PixelFormat); 55 | 56 | infodest.biBitCount = (ushort)Image.GetPixelFormatSize(imgdest.PixelFormat); 57 | ResizeImage(datasrc.Scan0, infosrc, datadest.Scan0, infodest); 58 | 59 | imgsrc.UnlockBits(datasrc); 60 | imgdest.UnlockBits(datadest); 61 | 62 | imgdest.Save("icondest.png", ImageFormat.Png); 63 | 64 | Console.ReadKey(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /TestResizeImage/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TestResizeImage")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("TestResizeImage")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c32c2a10-270a-4574-b0e1-b169ca98dd6f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /TestResizeImage/TestResizeImage.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {828EF737-BFC3-4980-B463-BACDE0EBEF91} 9 | Exe 10 | Properties 11 | TestResizeImage 12 | TestResizeImage 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x64 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | true 27 | 28 | 29 | x64 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Always 54 | 55 | 56 | 57 | 58 | Always 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /TestResizeImage/icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmiddelkoop/ImageResize/558b52ac4f158ecc30005553090daba764770134/TestResizeImage/icon.jpg --------------------------------------------------------------------------------