将多个图片合并到一个TIF文件里(非 GDAL) 优化版
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices; namespace Common
{ public class CreatTiff
{
#region 将图片列表合并到一个文件
/// <summary>
/// 多张图片合并
/// </summary>
/// <param name="img">图片列表</param>
/// <param name="dstFile">合并图片名</param>
/// <returns></returns>
public bool CreateTiffFile(Image[] img, string dstFile) {
return GetTiffFile(img, dstFile);
}
#endregion #region 将单个TIF添加到多页TIF中
/// <summary>
/// 将单个TIF添加到多页TIF中
/// </summary>
/// <param name="srcFile">单页TIFF地址</param>
/// <param name="dstFile">需要添加到的多页TIFF地址</param>
/// <returns></returns>
public bool AddTiffFile(string srcFile, string dstFile, string RootPath, int tifNumber)
{
try
{
string thumbnailImagePath = RootPath + "thumbnailImagePath.tif";
Image i1 = null;
//if (tifNumber > 9)//为解决内存不足想的拙劣解决方法
//{
// GetThumbnail(srcFile, thumbnailImagePath, 1150, 1850);
// i1 = Image.FromFile(thumbnailImagePath);
//}
//else
//{
// i1 = Image.FromFile(srcFile);
//}
i1 = Image.FromFile(srcFile);
Image loadImage = new Bitmap(i1); Image origionalFile = Image.FromFile(dstFile);
int PageNumber = getPageNumber(origionalFile);
Image[] img = new Image[PageNumber + ];
for (int i = ; i < PageNumber; i++)
{
origionalFile.SelectActiveFrame(FrameDimension.Page, i);
img[i] = new Bitmap(origionalFile);
}
img[PageNumber] = loadImage;
origionalFile.Dispose();
i1.Dispose();
return GetTiffFile(img, dstFile);
}
catch (Exception ex)
{
Log.Writer(ex, "合并TIF文件AddTiffFile()异常");
throw new Exception("TIF文件:"+ srcFile + " 处理错误!请检查文件是否损坏!");
}
}
#endregion #region 合并
/// <summary>
/// 合并
/// </summary>
/// <param name="img">图片列表</param>
/// <param name="dstFile">合并目的文件</param>
/// <returns></returns>
private bool GetTiffFile(Image[] img, string dstFile)
{
EncoderParameter SaveEncodeParam = null;
EncoderParameter CompressionEncodeParam = null;
EncoderParameters EncoderParams = null;
try
{
if (img == null) return false;
if (img.Length < ) return false;//如果只有一个文件,直接存成TIFF就好了,没有必要在这里处理
ImageCodecInfo codecInfo = ImageCodecInfo.GetImageEncoders()[];
if (codecInfo.FormatDescription != "TIFF") return false; for (int i = ; i < img.Length; i++)
{
if (img[i] == null)
break;
img[i] = (Image)ConvertToBitonal((Bitmap)img[i]); }
if (img.Length < ) return false; Encoder saveEncoder = Encoder.SaveFlag;
Encoder compressionEncoder = Encoder.Compression;
SaveEncodeParam = new EncoderParameter(saveEncoder, (long)EncoderValue.MultiFrame);
CompressionEncodeParam = new EncoderParameter(compressionEncoder, (long)EncoderValue.CompressionCCITT4);
EncoderParams = new EncoderParameters();
EncoderParams.Param[] = CompressionEncodeParam;
EncoderParams.Param[] = SaveEncodeParam; if (File.Exists(dstFile)) File.Delete(dstFile); img[].Save(dstFile, codecInfo, EncoderParams);
for (int i = ; i < img.Length; i++)
{
SaveEncodeParam = new EncoderParameter(saveEncoder, (long)EncoderValue.FrameDimensionPage);
CompressionEncodeParam = new EncoderParameter(compressionEncoder, (long)EncoderValue.CompressionCCITT4);
EncoderParams.Param[] = CompressionEncodeParam;
EncoderParams.Param[] = SaveEncodeParam;
img[].SaveAdd(img[i], EncoderParams); } SaveEncodeParam = new EncoderParameter(saveEncoder, (long)EncoderValue.Flush);
EncoderParams.Param[] = SaveEncodeParam;
img[].SaveAdd(EncoderParams);
}
catch (Exception ex)
{
Log.Writer(ex, "合并TIF文件异常");
return false;
}
finally
{
SaveEncodeParam.Dispose();
CompressionEncodeParam.Dispose();
EncoderParams.Dispose();
foreach (var item in img)
{
item.Dispose();
}
GC.Collect();
}
return true;
}
#endregion /// <summary>
/// 生成缩略图
/// </summary>
/// <param name="serverImagePath">图片地址</param>
/// <param name="thumbnailImagePath">缩略图地址</param>
/// <param name="width">图片宽度</param>
/// <param name="height">图片高度</param>
/// <param name="p"></param>
public static void GetThumbnail(string serverImagePath, string thumbnailImagePath, int width, int height)
{
System.Drawing.Image serverImage = System.Drawing.Image.FromFile(serverImagePath);
//画板大小
int towidth = width;
int toheight = height;
//缩略图矩形框的像素点
//int x = 0;
//int y = 0;
int ow = serverImage.Width;
int oh = serverImage.Height; if (ow > oh)
{
toheight = serverImage.Height * width / serverImage.Width;
}
else
{
towidth = serverImage.Width * height / serverImage.Height;
}
//新建一个bmp图片
System.Drawing.Image bm = new System.Drawing.Bitmap(width, height);
//新建一个画板
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bm);
//设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//清空画布并以透明背景色填充
g.Clear(System.Drawing.Color.White);
//在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(serverImage, new System.Drawing.Rectangle((width - towidth) / , (height - toheight) / , towidth, toheight),
, , ow, oh,
System.Drawing.GraphicsUnit.Pixel);
try
{
//以jpg格式保存缩略图
bm.Save(thumbnailImagePath, System.Drawing.Imaging.ImageFormat.Tiff);
}
catch (System.Exception e)
{
throw e;
}
finally
{
serverImage.Dispose();
bm.Dispose();
g.Dispose();
GC.Collect();
}
} 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, , );
}
}
else
{
source = original;
} // Lock source bitmap in memory
BitmapData sourceData = source.LockBits(new Rectangle(, , 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, , 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(, , destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed); // Create destination buffer
imageSize = destinationData.Stride * destinationData.Height;
byte[] destinationBuffer = new byte[imageSize]; int sourceIndex = ;
int destinationIndex = ;
int pixelTotal = ;
byte destinationValue = ;
int pixelValue = ;
int height = source.Height;
int width = source.Width;
int threshold = ; // Iterate lines
for (int y = ; y < height; y++)
{
sourceIndex = y * sourceData.Stride;
destinationIndex = y * destinationData.Stride;
destinationValue = ;
pixelValue = ; // Iterate pixels
for (int x = ; x < width; x++)
{
// Compute pixel brightness (i.e. total of Red, Green, and Blue values)
pixelTotal = sourceBuffer[sourceIndex + ] + sourceBuffer[sourceIndex + ] + sourceBuffer[sourceIndex + ];
if (pixelTotal > threshold)
{
destinationValue += (byte)pixelValue;
}
if (pixelValue == )
{
destinationBuffer[destinationIndex] = destinationValue;
destinationIndex++;
destinationValue = ;
pixelValue = ;
}
else
{
pixelValue >>= ;
}
sourceIndex += ;
}
if (pixelValue != )
{
destinationBuffer[destinationIndex] = destinationValue;
}
}
// Copy binary image data to destination bitmap
Marshal.Copy(destinationBuffer, , destinationData.Scan0, imageSize);
// Unlock destination bitmap
destination.UnlockBits(destinationData);
// Return
return destination;
} private int getPageNumber(Image img)
{
Guid objGuid = img.FrameDimensionsList[];
FrameDimension objDimension = new FrameDimension(objGuid);
//Gets the total number of frames in the .tiff file
int PageNumber = img.GetFrameCount(objDimension);
return PageNumber;
} }
}
将多个图片合并到一个TIF文件里(非 GDAL) 优化版的更多相关文章
- C# 将多个office文件转换及合并为一个PDF文件
PDF文件介绍 PDF(Portable Document Format )文件源于20世纪90年代初期,如今早已成为了一种最流行的的文件格式之一.因为PDF文件有很多优点: 支持跨平台和跨设备共享 ...
- 多个.txt文件合并到一个.txt文件中
如果想要将多个.txt文件合并到一个.txt文件中,可以先将所有.txt文件放到一个文件夹中,然后使用.bat文件完成任务. 例如,在一个文件夹下有1.txt, 2.txt, 3.txt三个文件,想把 ...
- 把当前文件夹的xlsx或xls文件合并到一个excel文件中的不同sheet中
把当前文件夹的xlsx或xls文件合并到一个excel文件中的不同sheet中步骤如下: 把需要合并的文件放到同一个文件夹 在该文件夹中新建一个excel文件 打开新建的excel问价,把鼠标放到sh ...
- 常用代码之五:RequireJS, 一个Define需要且只能有一个返回值/对象,一个JS文件里只能放一个Define.
RequireJS 介绍说一个JS文件里只能放一个Define,这个众所周知,不提. 关于Define,它需要有一个返回值/对象,且只能有一个返回值/对象,这一点却是好多帖子没有提到的,但又非常重要的 ...
- 查找一个Class到底在那一个jar文件里
整理自己的一些笔记,发觉这个命令 ,看起来是用来找一个Class到底在那一个jar文件里的. 虽然没有再测一下,估计是好使的. 先在博客园里记下来,防止自己忘掉. findstr /S /M org. ...
- Facebook图片存储系统Haystack——存小文件,本质上是将多个小文件合并为一个大文件来降低io次数,meta data里存偏移量
转自:http://yanyiwu.com/work/2015/01/04/Haystack.html 一篇14页的论文Facebook-Haystack, 看完之后我的印象里就四句话: 因为[传统文 ...
- 将STM32 iap hex文件与app hex文件合并为一个hex文件
日前公司产品需要增加远程升级功能,boot loader程序写好后交予生产部门使用时他们反馈每个产品程序需要刷写两次(一个boot loader 一个app程序),生产进度变慢浪费时间,于是乎研究如何 ...
- 一条命令将windows下多个ts文件合并为一个ts文件
首先在待合并的文件夹下创建concat.bat(名字随意啦),写入如下命令 copy /b "%~dp0"\*.ts "%~dp0"\new.ts 执行该命令后 ...
- python 读hdf4文件,再转写成一个tif文件
1.安装pyhdf包 (1)通过此链接查找并下载pyhdf包:https://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame(根据自己的系统及python版本选择 ...
随机推荐
- 添加JavaDoc
使用javadoc比较容易生成文档,命令如下: javadoc -d doc -sourcepath src/main/java/ -subpackages com -encoding UTF-8 - ...
- 一个可以参考的JVM内存分配
下面是java命令有关JVM内存分配的参数 JAVA_MEM_OPTS="" BITS=`java -version >& | -bit` if [ -n " ...
- 学校公文办公处理系统_基于ASP.NET和Swfupload、FlashPaper2.2、校讯通短信发送的开发
学校新来了一个主管教学的副校长,他对他以前工作学校的公文处理系统表示高度留念,于是乎叫我们也开发一个. 我就参考了那个学校的办公管理系统,发现其实功能也蛮简单的,就是一个文件上传下载的功能,选择用户组 ...
- 简单的redis测试
//这个方法会多一次 public function testRedisList(){ $num = 10; $user_id = uniqid(); //直接链接本地的redis $redis = ...
- 【经验分享】我经历的几门MOOC
这半年来,从1月初到6月底,在coursera上注册了4们有关数据分析/挖掘的课程.这些课程都是利用业余时间学习,每周基本上花5个小时左右.其中通过了3门,注销了一门.感觉还是学到了一些东西. 第一门 ...
- (Java编程思想)Thinking in Java
1. 为什么突然想去研读<Thinking in Java>? 最近终于下定决心撸了一本<Thinking in Java>第四版,虽然在此之前我就久闻这本书的大名,但一直未曾 ...
- git 创建标签
在Git中打标签非常简单,首先,切换到需要打标签的分支上: $ git branch * dev master $ git checkout master Switched to branch 'ma ...
- C++11模版元编程的应用
1.概述 关于C++11模板元的基本用法和常用技巧,我在程序员2015年2月B<C++11模版元编程>一文(后称前文)中已经做了详细地介绍,那么C++11模版元编程用来解决什么实际问题呢, ...
- 【Java】forward & redirect 的差异
1.从地址栏显示来说 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地 ...
- 模板, 保存&发布
单击“视图”菜单中的“幻灯片模板”按钮,会弹出“幻灯片母版”选项卡,在此选项卡中,可以修改当前PPT的模板, 例如网上下载的幻灯片上的LOGO都可在这里去除. 模板设计总结 1. 背景可以选择纯色,也 ...