private static byte BytesPerPixel(PixelFormat px)
{
switch (px)
{
case PixelFormat.Format16bppRgb555:
case PixelFormat.Format16bppRgb565:
case PixelFormat.Format16bppGrayScale:
case PixelFormat.Format16bppArgb1555: return 2;
case PixelFormat.Format24bppRgb: return 3;
case PixelFormat.Format32bppRgb: return 4;
case PixelFormat.Format32bppArgb: return 4;
case PixelFormat.Format32bppPArgb: return 4;
}
return 0;
}
public static Bitmap ThumbnailLow(Bitmap img, Size sz)
{
if (img == null || sz.IsEmpty) return null;
if (sz.Width > img.Width) sz = new Size(img.Width, sz.Height);
if (sz.Height > img.Height) sz = new Size(sz.Width, img.Height);
PixelFormat px = img.PixelFormat;
PixelFormat pxn = PixelFormat.Format16bppRgb565;
if (px == PixelFormat.Format32bppArgb || px == PixelFormat.Format32bppPArgb ||
px == PixelFormat.Format32bppRgb) pxn = PixelFormat.Format24bppRgb;
byte bytesPerPixel = BytesPerPixel(px), bytesPerPixel2 = BytesPerPixel(pxn);
Bitmap nueva = new Bitmap(sz.Width, sz.Height, pxn);
BitmapData bmpData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, px);
BitmapData bmpData2 = nueva.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.ReadWrite, pxn);
// 快速转换
float inc_djn = img.Width / (float)sz.Width;
float inc_din = img.Height / (float)sz.Height;
float din = 0, djn = 0;
bool _16bits = bytesPerPixel == 2 || bytesPerPixel2 == 2;
unsafe
{
byte* ptr = (byte*)(bmpData.Scan0);
byte* ptr2 = (byte*)(bmpData2.Scan0);
int nOffset = bmpData.Stride - (bmpData.Width * bytesPerPixel);
int nOffset2 = bmpData2.Stride - (bmpData2.Width * bytesPerPixel2);
int h = bmpData.Height, w = bmpData.Width;
for (int i = 0; i < h; i++)
{
bool lok = i >= din;
djn = 0;
for (int j = 0; j < w; j++)
{
if (lok && j >= djn)
{
ptr2[0] = ptr[0];
ptr2[1] = ptr[1];
if (!_16bits) ptr2[2] = ptr[2];
ptr2 += bytesPerPixel2;
djn += inc_djn;
}
ptr += bytesPerPixel;
}
if (lok) { ptr2 += nOffset2; din += inc_din; }
ptr += nOffset;
}
}
img.UnlockBits(bmpData);
nueva.UnlockBits(bmpData2);
return nueva;
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;
namespace ol
{
public partial class Form1 : Form
{
if (fScaleRatio < 1.0)
{
Size sz = new Size(nNewWidth, nNewHeight);
LogTraceInfo("new Bitmap", true);
//Method 1: need 796,828 ms
oNewImage = new Bitmap(oOriginalImage, nNewWidth, nNewHeight);
//Method 2: need 1546,1578 ms
//oNewImage = ThumbnailLow((Bitmap)oOriginalImage, sz);
//Method 3: need 812,828 ms
//oNewImage = ThumbnailAAAA((Bitmap)oOriginalImage, nNewWidth, nNewHeight);
//Method 4: need 765,875 ms
//oNewImage = oOriginalImage.GetThumbnailImage(nNewWidth, nNewHeight, new Image.GetThumbnailImageAbort(ImageThumbnailAbortCallback), IntPtr.Zero);
private static byte BytesPerPixel(PixelFormat px)
{
switch (px)
{
case PixelFormat.Format16bppRgb555:
case PixelFormat.Format16bppRgb565:
case PixelFormat.Format16bppGrayScale:
case PixelFormat.Format16bppArgb1555: return 2;
case PixelFormat.Format24bppRgb: return 3;
case PixelFormat.Format32bppRgb: return 4;
case PixelFormat.Format32bppArgb: return 4;
case PixelFormat.Format32bppPArgb: return 4;
}
return 0;
}
public static Bitmap ThumbnailLow(Bitmap img, Size sz)
{
if (img == null || sz.IsEmpty) return null;
if (sz.Width > img.Width) sz = new Size(img.Width, sz.Height);
if (sz.Height > img.Height) sz = new Size(sz.Width, img.Height);
PixelFormat px = img.PixelFormat;
PixelFormat pxn = PixelFormat.Format16bppRgb565;
if (px == PixelFormat.Format32bppArgb || px == PixelFormat.Format32bppPArgb ||
px == PixelFormat.Format32bppRgb) pxn = PixelFormat.Format24bppRgb;
byte bytesPerPixel = BytesPerPixel(px), bytesPerPixel2 = BytesPerPixel(pxn);
Bitmap nueva = new Bitmap(sz.Width, sz.Height, pxn);
BitmapData bmpData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, px);
BitmapData bmpData2 = nueva.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.ReadWrite, pxn);
// 快速转换
float inc_djn = img.Width / (float)sz.Width;
float inc_din = img.Height / (float)sz.Height;
float din = 0, djn = 0;
bool _16bits = bytesPerPixel == 2 || bytesPerPixel2 == 2;
unsafe
{
byte* ptr = (byte*)(bmpData.Scan0);
byte* ptr2 = (byte*)(bmpData2.Scan0);
int nOffset = bmpData.Stride - (bmpData.Width * bytesPerPixel);
int nOffset2 = bmpData2.Stride - (bmpData2.Width * bytesPerPixel2);
int h = bmpData.Height, w = bmpData.Width;
for (int i = 0; i < h; i++)
{
bool lok = i >= din;
djn = 0;
for (int j = 0; j < w; j++)
{
if (lok && j >= djn)
{
ptr2[0] = ptr[0];
ptr2[1] = ptr[1];
if (!_16bits) ptr2[2] = ptr[2];
ptr2 += bytesPerPixel2;
djn += inc_djn;
}
ptr += bytesPerPixel;
}
if (lok) { ptr2 += nOffset2; din += inc_din; }
ptr += nOffset;
}
}
img.UnlockBits(bmpData);
nueva.UnlockBits(bmpData2);
return nueva;
}
public static Bitmap ThumbnailAAAA(Bitmap img, int ww, int hh)
{
Bitmap Bmp = new Bitmap((int)ww, (int)hh);
Graphics Myg = Graphics.FromImage(Bmp);
Myg.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
Myg.DrawImage(img, 0, 0, ww, hh);
return Bmp;
}
}