您的位置:首页 > 其它

将多个图片合并到一个TIF文件里(非 GDAL)

2013-04-16 21:14 465 查看
不知道为什么,网上对TIF的操作的资料少得可怜,包括CodeProject上都没有找到多少,在网上大多用GDAL,但这个东西,对只想做个合并图片的功能来说,实在是牛刀杀鸡,(9个DLL要带全,相当的恐怖)而且对完成的生成和读取TIF的描述也是相当的少,一般都是用来处理GIS。

原下载:http://download.csdn.net/detail/patizi/200992 但那个写得比较乱,我封装成了一个类!!!

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
//using System.Text;

namespace SaveMultipageTiffArticle
{
public class CreatTiff
{
public bool CreateTiffFile(Image[] img, string dstFile)
{
return GetTiffFile(img, dstFile);
}
public bool AddTiffFile(string srcFile, string dstFile)
{
Image i1 = Image.FromFile(srcFile);

Image loadImage =new Bitmap(i1);
//FileStream fr = File.Open(dstFile, FileMode.Open, FileAccess.ReadWrite);
Image origionalFile =Image.FromFile(dstFile);
int PageNumber = getPageNumber(origionalFile);
Image [] img =new Image[PageNumber+1];
for (int i = 0; i < PageNumber; i++)
{
origionalFile.SelectActiveFrame(FrameDimension.Page, i);
img[i] =new Bitmap(  origionalFile);
}
img[PageNumber] = loadImage;
origionalFile.Dispose();
i1.Dispose();

return GetTiffFile (img,dstFile );
}
private  bool GetTiffFile(Image[] img, string dstFile)
{
try
{
if (img == null) return false;
if (img.Length < 2) return false;//如果只有一个文件,直接存成TIFF就好了,没有必要在这里处理
ImageCodecInfo codecInfo = ImageCodecInfo.GetImageEncoders()[3];
if (codecInfo.FormatDescription != "TIFF") return false;

for (int i = 0; i < img.Length; i++)
{
if (img[i] == null)
break;
img[i] = (Image)ConvertToBitonal((Bitmap)img[i]);

}
if (img.Length <2) return false;

Encoder saveEncoder = Encoder.SaveFlag;
Encoder compressionEncoder = Encoder.Compression;
EncoderParameter SaveEncodeParam = new EncoderParameter(saveEncoder, (long)EncoderValue.MultiFrame);
EncoderParameter CompressionEncodeParam = new EncoderParameter(compressionEncoder, (long)EncoderValue.CompressionCCITT4);
EncoderParameters EncoderParams = new EncoderParameters(2);
EncoderParams.Param[0] = CompressionEncodeParam;
EncoderParams.Param[1] = SaveEncodeParam;

if (File.Exists (dstFile)) File.Delete(dstFile);
img[0].Save(dstFile, codecInfo, EncoderParams);
for (int i = 1; i < img.Length; i++)
{
SaveEncodeParam = new EncoderParameter(saveEncoder, (long)EncoderValue.FrameDimensionPage);
CompressionEncodeParam = new EncoderParameter(compressionEncoder, (long)EncoderValue.CompressionCCITT4);
EncoderParams.Param[0] = CompressionEncodeParam;
EncoderParams.Param[1] = SaveEncodeParam;
img[0].SaveAdd(img[i], EncoderParams);

}

SaveEncodeParam = new EncoderParameter(saveEncoder, (long)EncoderValue.Flush);
EncoderParams.Param[0] = SaveEncodeParam;
img[0].SaveAdd(EncoderParams);
}
catch (Exception ex)
{
return false;
}
return true;
}

private  Bitmap ConvertToBitonal(Bitmap original)
{
Bitmap source = null;

// If original bitmap is not already in 32 BPP, ARGB format, then convert
if (original.PixelFormat != PixelFormat.Format32bppArgb)
{
source = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb);
source.SetResolution(original.HorizontalResolution, original.VerticalResolution);
using (Graphics g = Graphics.FromImage(source))
{
g.DrawImageUnscaled(original, 0, 0);
}
}
else
{
source = original;
}

// Lock source bitmap in memory
BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

// Copy image data to binary array
int imageSize = sourceData.Stride * sourceData.Height;
byte[] sourceBuffer = new byte[imageSize];
Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

// Unlock source bitmap
source.UnlockBits(sourceData);

// Create destination bitmap
Bitmap destination = new Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed);

// Lock destination bitmap in memory
BitmapData destinationData = destination.LockBits(new Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);

// Create destination buffer
imageSize = destinationData.Stride * destinationData.Height;
byte[] destinationBuffer = new byte[imageSize];

int sourceIndex = 0;
int destinationIndex = 0;
int pixelTotal = 0;
byte destinationValue = 0;
int pixelValue = 128;
int height = source.Height;
int width = source.Width;
int threshold = 500;

// Iterate lines
for (int y = 0; y < height; y++)
{
sourceIndex = y * sourceData.Stride;
destinationIndex = y * destinationData.Stride;
destinationValue = 0;
pixelValue = 128;

// Iterate pixels
for (int x = 0; x < width; x++)
{
// Compute pixel brightness (i.e. total of Red, Green, and Blue values)
pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] + sourceBuffer[sourceIndex + 3];
if (pixelTotal > threshold)
{
destinationValue += (byte)pixelValue;
}
if (pixelValue == 1)
{
destinationBuffer[destinationIndex] = destinationValue;
destinationIndex++;
destinationValue = 0;
pixelValue = 128;
}
else
{
pixelValue >>= 1;
}
sourceIndex += 4;
}
if (pixelValue != 128)
{
destinationBuffer[destinationIndex] = destinationValue;
}
}

// Copy binary image data to destination bitmap
Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);

// Unlock destination bitmap
destination.UnlockBits(destinationData);

// Return
return destination;
}

private int getPageNumber(Image img)
{

Guid objGuid = img.FrameDimensionsList[0];
FrameDimension objDimension = new FrameDimension(objGuid);

//Gets the total number of frames in the .tiff file
int PageNumber = img.GetFrameCount(objDimension);

return PageNumber;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: