You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

285 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace WpfPdfReader
{
public class ImageHelper
{
public static byte[] ImageToBytes(Image image)
{
if (image == null)
return null;
using (MemoryStream ms = new MemoryStream())
{
using (Bitmap bitmap = new Bitmap(image))
{
try
{
bitmap.Save(ms, image.RawFormat);
}
catch
{
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
}
return ms.ToArray();
}
}
}
public static Image ReadImage(byte[] bytes)
{
if (bytes == null)
return null;
//如果用using 会引起 "A generic error occurred in GDI+"
MemoryStream memStream = new MemoryStream(bytes);
{
Image img = Image.FromStream(memStream);
//img.Save(@"test2.jpg");
return img;
}
}
/// <summary>
/// 保持纵横比
/// </summary>
/// <param name="srcImage"></param>
/// <param name="newSize"></param>
/// <returns></returns>
public static Image GetThumbnailImage(Image srcImage, Size newSize)
{
if (srcImage != null && newSize != null)
{
int srcWidth = srcImage.Width;
int srcHeight = srcImage.Height;
int dstHeight = newSize.Height;
int dstWidth = newSize.Width;
if (srcWidth > srcHeight)
{
dstHeight = newSize.Height;
dstWidth = Convert.ToInt32(dstHeight * (new decimal(srcWidth) / new decimal(srcHeight)));
}
else
{
dstWidth = newSize.Width;
dstHeight = Convert.ToInt32(dstWidth * (new decimal(srcHeight) / new decimal(srcWidth)));
}
return GetImage(srcImage, new Size(dstWidth, dstHeight));
}
else
return null;
}
/// <summary>
/// 根据是否需要保持纵横比返回缩略图
/// </summary>
/// <param name="srcImage">原始图像</param>
/// <param name="newSize">新图像大小</param>
/// <param name="keepAspectRatio">是否保持纵横比</param>
/// <returns></returns>
public static Image GetThumbnailImage(Image srcImage, Size newSize, bool keepAspectRatio)
{
if (keepAspectRatio)
return GetThumbnailImage(srcImage, newSize);
else
{
return GetImage(srcImage, newSize);
}
}
public static Icon ImageToIcon(Image image, string fileName)
{
Bitmap bmp = image as Bitmap;
Icon icon = System.Drawing.Icon.FromHandle(bmp.GetHicon());
FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);
icon.Save(fs);
fs.Close();
return icon;
}
private static Image GetImage(Image srcImage, Size newSize)
{
int srcWidth = srcImage.Width;
int srcHeight = srcImage.Height;
int dstHeight = newSize.Height;
int dstWidth = newSize.Width;
Image dstImage = new Bitmap(dstWidth, dstHeight);
Graphics g = Graphics.FromImage(dstImage);
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.High;
Rectangle dstRect = new Rectangle(0, 0, dstWidth, dstHeight);
Rectangle srcRect = new Rectangle(0, 0, srcWidth, srcHeight);
Image newImage = srcImage.Clone() as Image;
g.DrawImage(newImage, dstRect, srcRect, GraphicsUnit.Pixel);
using (MemoryStream ms = new MemoryStream())
{
try
{
dstImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
dstImage = Image.FromStream(ms);
}
catch { }
}
g.Dispose();
return dstImage;
}
private static long totaltime;
private static int count;
/// <summary>
/// 上下合并两张一样大小的图片
/// </summary>
/// <param name="srcImage1">图片1</param>
/// <param name="srcImage2">图片2</param>
/// <returns>返回合并后的图片内存流</returns>
public static MemoryStream CombineImageVertical(System.Drawing.Image srcImage1, System.Drawing.Image srcImage2)
{
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Start();
count++;
int srcWidth = srcImage1.Width;
int srcHeight = srcImage1.Height;
int dstHeight = srcHeight + srcImage2.Height + 5;
int dstWidth = srcWidth;
System.Drawing.Image dstImage = new Bitmap(dstWidth, dstHeight);
Graphics g = Graphics.FromImage(dstImage);
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.High;
System.Drawing.Rectangle dstRect1 = new System.Drawing.Rectangle(0, 0, srcWidth, srcHeight);
System.Drawing.Rectangle srcRect1 = new System.Drawing.Rectangle(0, 0, srcWidth, srcHeight);
g.DrawImage(srcImage1, dstRect1, srcRect1, GraphicsUnit.Pixel);
System.Drawing.Rectangle dstRect2 = new System.Drawing.Rectangle(0, srcHeight + 5, srcWidth, srcHeight);
System.Drawing.Rectangle srcRect2 = new System.Drawing.Rectangle(0, 0, srcWidth, srcHeight);
g.DrawImage(srcImage2, dstRect2, srcRect2, GraphicsUnit.Pixel);
MemoryStream ms = new MemoryStream();
dstImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
dstImage.Dispose();
g.Dispose();
watch.Stop();
System.Diagnostics.Debug.WriteLine(watch.ElapsedMilliseconds);
totaltime += watch.ElapsedMilliseconds;
System.Diagnostics.Debug.WriteLine(string.Format("average time:{0}", (double)totaltime / count));
return ms;
}
public static MemoryStream MergeImageVertical(System.Drawing.Image srcImage1, System.Drawing.Image srcImage2)
{
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Start();
count++;
int dstHeight = srcImage1.Height + srcImage2.Height + 7;
int dstWidth = srcImage1.Width > srcImage2.Width ? srcImage1.Width : srcImage2.Width;
Bitmap bmp = new Bitmap(dstWidth, dstHeight, PixelFormat.Format24bppRgb);
var imageData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, dstWidth, dstHeight), ImageLockMode.ReadWrite, bmp.PixelFormat);
Bitmap bmp1 = srcImage1 as System.Drawing.Bitmap;
Bitmap bmp2 = srcImage2 as System.Drawing.Bitmap;
var imageData1 = bmp1.LockBits(new System.Drawing.Rectangle(0, 0, srcImage1.Width, srcImage1.Height), ImageLockMode.ReadOnly, bmp1.PixelFormat);
var imageData2 = bmp2.LockBits(new System.Drawing.Rectangle(0, 0, srcImage2.Width, srcImage2.Height), ImageLockMode.ReadOnly, bmp2.PixelFormat);
int bitsPerPixel = ((int)bmp1.PixelFormat >> 8) & 0xFF;
int bpp = bitsPerPixel / 8;
unsafe
{
byte* ptrDest = (byte*)imageData.Scan0;
byte* ptrSrc = (byte*)imageData1.Scan0;
int height = srcImage1.Height;
int width = srcImage1.Width;
for (int y = 0; y < height; y++)
{
byte* pl = ptrDest;
byte* sl = ptrSrc;
for (int x = 0; x < width; x++)
{
pl[0] = sl[0]; //b
pl[1] = sl[1]; //g
pl[2] = sl[2]; //r
pl += 3;
sl += 3;
}
ptrDest += imageData.Stride;
ptrSrc += imageData1.Stride;
}
bmp1.UnlockBits(imageData1);
for (int y = 0; y < 7; y++)
{
byte* pl = ptrDest;
for (int x = 0; x < dstWidth; x++)
{
pl[0] = (byte)126;
pl[1] = (byte)167;
pl[2] = (byte)117;
pl += 3;
}
ptrDest += imageData.Stride;
}
height = srcImage2.Height;
width = srcImage2.Width;
ptrSrc = (byte*)imageData2.Scan0;
for (int y = 0; y < height; y++)
{
byte* pl = ptrDest;
byte* sl = ptrSrc;
for (int x = 0; x < width; x++)
{
pl[0] = sl[0]; //b
pl[1] = sl[1]; //g
pl[2] = sl[2]; //r
pl += 3;
sl += 3;
}
ptrDest += imageData.Stride;
ptrSrc += imageData2.Stride;
}
ptrDest = (byte*)IntPtr.Zero;
ptrSrc = (byte*)IntPtr.Zero;
bmp2.UnlockBits(imageData2);
}
bmp.UnlockBits(imageData);
imageData1 = null;
imageData2 = null;
imageData = null;
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
bmp.Dispose();
System.Diagnostics.Debug.WriteLine(watch.ElapsedMilliseconds);
totaltime += watch.ElapsedMilliseconds;
System.Diagnostics.Debug.WriteLine(string.Format("average time:{0}", (double)totaltime / count));
return ms;
}
}
}