C#:如何通过 MemoryStream 将多页 TIFF 转换为一个长图像?
C#: How do I convert a multi-page TIFF via MemoryStream into one long image?
所以我已经能够获取多页 TIFF 文件并将其转换为单个 jpeg 图像,但它会展平 TIFF。通过展平它,我的意思是它只有 returns 第一页。目标是检索 TIFF(通过内存流),打开 TIFF 的每一页并将其附加到新的 jpeg(或任何网络图像)。从而创建一个长图像,无需插件的帮助即可在网络上查看。我确实安装了 MODI.dll,但我不确定在这种情况下如何使用它,但它是一个选项。
源代码(使用 FileHandler):
#region multi-page tiff to single page jpeg
var byteFiles = dfSelectedDocument.File.FileBytes; // <-- FileBytes is a byte[] or byte array source.
byte[] jpegBytes;
using( var inStream = new MemoryStream( byteFiles ) )
using( var outStream = new MemoryStream() ) {
System.Drawing.Image.FromStream( inStream ).Save( outStream, ImageFormat.Jpeg );
jpegBytes = outStream.ToArray();
}
context.Response.ContentType = "image/JPEG";
context.Response.AddHeader( "content-disposition",
string.Format( "attachment;filename=\"{0}\"",
dfSelectedDocument.File.FileName.Replace( ".tiff", ".jpg" ) )
);
context.Response.Buffer = true;
context.Response.BinaryWrite( jpegBytes );
#endregion
你压缩过jpeg吗?
https://msdn.microsoft.com/en-us/library/bb882583(v=vs.110).aspx
我猜你必须循环遍历 TIFF 中的每一帧。
以下是 Split multi page tiff file 的摘录:
private void Split(string pstrInputFilePath, string pstrOutputPath)
{
//Get the frame dimension list from the image of the file and
Image tiffImage = Image.FromFile(pstrInputFilePath);
//get the globally unique identifier (GUID)
Guid objGuid = tiffImage.FrameDimensionsList[0];
//create the frame dimension
FrameDimension dimension = new FrameDimension(objGuid);
//Gets the total number of frames in the .tiff file
int noOfPages = tiffImage.GetFrameCount(dimension);
ImageCodecInfo encodeInfo = null;
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
for (int j = 0; j < imageEncoders.Length; j++)
{
if (imageEncoders[j].MimeType == "image/tiff")
{
encodeInfo = imageEncoders[j];
break;
}
}
// Save the tiff file in the output directory.
if (!Directory.Exists(pstrOutputPath))
Directory.CreateDirectory(pstrOutputPath);
foreach (Guid guid in tiffImage.FrameDimensionsList)
{
for (int index = 0; index < noOfPages; index++)
{
FrameDimension currentFrame = new FrameDimension(guid);
tiffImage.SelectActiveFrame(currentFrame, index);
tiffImage.Save(string.Concat(pstrOutputPath, @"\", index, ".TIF"), encodeInfo, null);
}
}
}
您应该能够调整上述逻辑以附加到您的 JPG 上,而不是创建单独的文件。
如果您在使用其他答案中建议的 SelectActiveFrame
方法时遇到可怕的 "A generic error occurred in GDI+" 错误(可以说是所有错误中的 Rickroll),我强烈建议使用 System.Windows.Media.Imaging.TiffBitmapDecoder
class(您需要向 PresentationCore.dll
框架库添加 Reference)。
下面是一个示例代码(它将所有 TIFF 帧放入标准位图列表):
List<System.Drawing.Bitmap> bmpLst = new List<System.Drawing.Bitmap>();
using (var msTemp = new MemoryStream(data))
{
TiffBitmapDecoder decoder = new TiffBitmapDecoder(msTemp, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
int totFrames = decoder.Frames.Count;
for (int i = 0; i < totFrames; ++i)
{
// Create bitmap to hold the single frame
System.Drawing.Bitmap bmpSingleFrame = BitmapFromSource(decoder.Frames[i]);
// add the frame (as a bitmap) to the bitmap list
bmpLst.Add(bmpSingleFrame);
}
}
这里是 BitmapFromSource
辅助方法:
public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
Bitmap bitmap;
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
bitmap = new Bitmap(outStream);
}
return bitmap;
}
有关此解决方法的更多信息,我还建议 read this blog post 我写道。
所以我已经能够获取多页 TIFF 文件并将其转换为单个 jpeg 图像,但它会展平 TIFF。通过展平它,我的意思是它只有 returns 第一页。目标是检索 TIFF(通过内存流),打开 TIFF 的每一页并将其附加到新的 jpeg(或任何网络图像)。从而创建一个长图像,无需插件的帮助即可在网络上查看。我确实安装了 MODI.dll,但我不确定在这种情况下如何使用它,但它是一个选项。
源代码(使用 FileHandler):
#region multi-page tiff to single page jpeg var byteFiles = dfSelectedDocument.File.FileBytes; // <-- FileBytes is a byte[] or byte array source. byte[] jpegBytes; using( var inStream = new MemoryStream( byteFiles ) ) using( var outStream = new MemoryStream() ) { System.Drawing.Image.FromStream( inStream ).Save( outStream, ImageFormat.Jpeg ); jpegBytes = outStream.ToArray(); } context.Response.ContentType = "image/JPEG"; context.Response.AddHeader( "content-disposition", string.Format( "attachment;filename=\"{0}\"", dfSelectedDocument.File.FileName.Replace( ".tiff", ".jpg" ) ) ); context.Response.Buffer = true; context.Response.BinaryWrite( jpegBytes ); #endregion
你压缩过jpeg吗? https://msdn.microsoft.com/en-us/library/bb882583(v=vs.110).aspx
我猜你必须循环遍历 TIFF 中的每一帧。
以下是 Split multi page tiff file 的摘录:
private void Split(string pstrInputFilePath, string pstrOutputPath)
{
//Get the frame dimension list from the image of the file and
Image tiffImage = Image.FromFile(pstrInputFilePath);
//get the globally unique identifier (GUID)
Guid objGuid = tiffImage.FrameDimensionsList[0];
//create the frame dimension
FrameDimension dimension = new FrameDimension(objGuid);
//Gets the total number of frames in the .tiff file
int noOfPages = tiffImage.GetFrameCount(dimension);
ImageCodecInfo encodeInfo = null;
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
for (int j = 0; j < imageEncoders.Length; j++)
{
if (imageEncoders[j].MimeType == "image/tiff")
{
encodeInfo = imageEncoders[j];
break;
}
}
// Save the tiff file in the output directory.
if (!Directory.Exists(pstrOutputPath))
Directory.CreateDirectory(pstrOutputPath);
foreach (Guid guid in tiffImage.FrameDimensionsList)
{
for (int index = 0; index < noOfPages; index++)
{
FrameDimension currentFrame = new FrameDimension(guid);
tiffImage.SelectActiveFrame(currentFrame, index);
tiffImage.Save(string.Concat(pstrOutputPath, @"\", index, ".TIF"), encodeInfo, null);
}
}
}
您应该能够调整上述逻辑以附加到您的 JPG 上,而不是创建单独的文件。
如果您在使用其他答案中建议的 SelectActiveFrame
方法时遇到可怕的 "A generic error occurred in GDI+" 错误(可以说是所有错误中的 Rickroll),我强烈建议使用 System.Windows.Media.Imaging.TiffBitmapDecoder
class(您需要向 PresentationCore.dll
框架库添加 Reference)。
下面是一个示例代码(它将所有 TIFF 帧放入标准位图列表):
List<System.Drawing.Bitmap> bmpLst = new List<System.Drawing.Bitmap>();
using (var msTemp = new MemoryStream(data))
{
TiffBitmapDecoder decoder = new TiffBitmapDecoder(msTemp, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
int totFrames = decoder.Frames.Count;
for (int i = 0; i < totFrames; ++i)
{
// Create bitmap to hold the single frame
System.Drawing.Bitmap bmpSingleFrame = BitmapFromSource(decoder.Frames[i]);
// add the frame (as a bitmap) to the bitmap list
bmpLst.Add(bmpSingleFrame);
}
}
这里是 BitmapFromSource
辅助方法:
public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
Bitmap bitmap;
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
bitmap = new Bitmap(outStream);
}
return bitmap;
}
有关此解决方法的更多信息,我还建议 read this blog post 我写道。