[英]C#: How do I convert a multi-page TIFF via MemoryStream into one long image?
So I have been able to take a multi-page TIFF file and convert it to a single jpeg image but it flattens the TIFF. 因此,我已经能够提取多页TIFF文件并将其转换为单个jpeg图像,但它会使TIFF变平。 By flatten it, I mean it only returns the first page.
展平它是指它仅返回第一页。 The goal is to retrieve the TIFF (via memory stream), open each page of the TIFF and append it to a new jpeg (or any web image).
目标是检索TIFF(通过内存流),打开TIFF的每个页面,并将其附加到新的jpeg(或任何Web图像)上。 Thus creating one long image to view on the web without the aid of a plugin.
因此,无需借助插件即可创建一个长图像以在网络上查看。 I do have the MODI.dll installed but I am not sure how to use it in this instance but it is an option.
我确实安装了MODI.dll,但不确定在这种情况下如何使用它,但这是一个选择。
Source Code (using a FileHandler): 源代码(使用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
have you compressed the jpeg? 您压缩了jpeg吗? https://msdn.microsoft.com/en-us/library/bb882583(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/bb882583(v=vs.110).aspx
I'm guessing that you'll have to loop over each frame in the TIFF. 我猜您将不得不遍历TIFF中的每个帧。
Here's an excerpt from Split multi page tiff file : 这是拆分多页tiff文件的摘录:
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);
}
}
}
You should be able to adapt the logic above to append onto your JPG rather than create separate files. 您应该能够调整上述逻辑以附加到JPG上,而不是创建单独的文件。
In case you get the dreadful "A generic error occurred in GDI+" error (which is arguably the Rickroll of all errors) when using the SelectActiveFrame
method suggested in the other answers, I strongly suggest to use the System.Windows.Media.Imaging.TiffBitmapDecoder
class instead (you will need to add a Reference to the PresentationCore.dll
framework library). 如果使用其他答案中建议的
SelectActiveFrame
方法时遇到可怕的“ GDI +中发生一般性错误”错误(可以说是所有错误的Rickroll),强烈建议使用System.Windows.Media.Imaging.TiffBitmapDecoder
类(您将需要添加对PresentationCore.dll
框架库的引用 )。
Here's an example code that does just that (it puts all the TIFF frames into a list of standard Bitmaps): 这是一个示例代码,它就是这样做的(它将所有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);
}
}
And here's the BitmapFromSource
helper method: 这是
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;
}
For further info regarding this workaround, I also suggest to read this blog post I wrote. 有关此变通办法的更多信息,我也建议阅读我写的这篇博客文章 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.