我为我的 Web 应用程序创建了 Tiff 文件查看器,它运行良好。但问题是我需要以原始尺寸显示一些大图像(4000 X 2000 - 5+ MB)。
是否可以压缩图像的大小,然后将流发送到 ashx 页面上的响应流?
请注意,我所有的图像都是扫描的黑白图像。但是为了预防起见,我想检查是否将特定于黑白图像的压缩算法应用于图像。
查看以下 TiffHelper 类的代码
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Drawing.Drawing2D;
public class TiffHelper
{
public static int GetPageCount(String filePath)
{
int pageCount = 0;
try
{
using (Image img = Image.FromStream(
new FileStream(filePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite)
))
{
pageCount = img.GetFrameCount(FrameDimension.Page);
}
}
catch (Exception ex)
{
CException.SuppressException(ex);
pageCount = -1;
}
return pageCount;
}
public static Image GetTiffImage(String sourceFile, int pageNumber, int thumbnailSize, int degree)
{
MemoryStream ms = null;
Image sourceImage = null;
Image returnImage = null;
try
{
sourceImage = Image.FromStream(
new FileStream(sourceFile,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite)
);
ms = new MemoryStream();
FrameDimension FrDim = new FrameDimension(sourceImage.FrameDimensionsList[0]);
sourceImage.SelectActiveFrame(FrDim, pageNumber - 1);
sourceImage.Save(ms, ImageFormat.Tiff);
/*
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, 90);
ImageCodecInfo tiffCodec = GetEncoderInfo("image/tiff");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
sourceImage.Save(ms, tiffCodec, encoderParams);
*/
/*
EncoderParameters iparams = new EncoderParameters(2);
iparams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
iparams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
*
sourceImage.Save(ms, GetEncoderInfo("image/tiff"), iparams);
*/
int height = sourceImage.Height;
int width = sourceImage.Width;
if (thumbnailSize > 0)
{
if (sourceImage.Width < sourceImage.Height)
{
width = thumbnailSize;
height = sourceImage.Height * thumbnailSize / sourceImage.Width;
}
else
{
width = sourceImage.Width * thumbnailSize / sourceImage.Height;
height = thumbnailSize;
}
}
//returnImage = ResizeImage(Image.FromStream(ms), new Size(width, height));
returnImage = Image.FromStream(ms).GetThumbnailImage(width, height, null, IntPtr.Zero);
returnImage.RotateFlip(GetFlipType(degree));
}
catch (Exception ex)
{
CException.SuppressException(ex);
}
finally
{
ms.Dispose();
sourceImage.Dispose();
}
return returnImage;
}
private static Image ResizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return (Image)b;
}
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
for (int i = 0; i < codecs.Length; i++)
{
if (codecs[i].MimeType == mimeType)
{
return codecs[i];
}
}
return null;
}
private static RotateFlipType GetFlipType(int degree)
{
switch (degree)
{
case 90:
return RotateFlipType.Rotate90FlipNone;
case 180:
return RotateFlipType.Rotate180FlipNone;
case 270:
return RotateFlipType.Rotate270FlipNone;
case -90:
return RotateFlipType.Rotate90FlipXY;
case -180:
return RotateFlipType.Rotate180FlipNone;
case -270:
return RotateFlipType.Rotate270FlipXY;
default:
return RotateFlipType.RotateNoneFlipNone;
}
}
}