BitMiracle
using BitMiracle.LibTiff.Classic;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using Emgu.CV;
using Emgu.Util;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Emgu.CV.Structure;
using System.Runtime.InteropServices;
using Emgu.CV.CvEnum;
namespace TestWinform
{
public class BitMiracle
{
public static void ConvertImageByEmgu(string[] lstTifFile, string outputFolderPath, string outputFileName)
{
try
{
List<Bitmap> lstCompressFiles = new List<Bitmap>();
foreach (var tmpFile in lstTifFile)
{
Image image1 = Image.FromFile(tmpFile);
int totalImage2 = image1.GetFrameCount(FrameDimension.Page);
for (int i = 0; i < totalImage2; i++)
{
image1.SelectActiveFrame(FrameDimension.Page, i);
string pngFilePath = Path.Combine(outputFolderPath, Guid.NewGuid().ToString() + ".png");
using (Bitmap bmp = new Bitmap(image1))
{
bmp.Save(pngFilePath, ImageFormat.Png);
}
if (File.Exists(pngFilePath))
{
string tmpCompressionFilePath = GetCompressImgByEmgu(pngFilePath, outputFolderPath);
File.Delete(pngFilePath);
if (File.Exists(tmpCompressionFilePath))
{
Image tmpCompressionImg = Image.FromFile(tmpCompressionFilePath);
Bitmap tmpBmp = new Bitmap(tmpCompressionImg);
lstCompressFiles.Add(tmpBmp);
tmpCompressionImg.Dispose();
//File.Delete(tmpCompressionFilePath);
}
}
}
}
if (lstCompressFiles.Count > 0)
{
string mergeFilEPath = Path.Combine(outputFolderPath, outputFileName);
Jpegs2Tiff(lstCompressFiles, mergeFilEPath);
}
}
catch (Exception ex)
{
throw ex;
}
}
private static string GetCompressImgByEmgu(string pngFilePath, string outPutFolderPath)
{
string compressionFile = string.Empty;
using (var image = new Image<Gray, Byte>(pngFilePath))
{
var grayImage = image.Convert<Gray, Byte>();//转为灰度图
var threshImage = grayImage.CopyBlank();
//var src = grayImage.Mat;
//Mat dstMat = new Mat();
//中值
//CvInvoke.Blur(src, dstMat, new Size(3, 3), new Point(-1, 1));
//腐蚀
//var element = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Cross, new Size(3, 3), new Point(-1, -1));
//CvInvoke.Erode(src, dstMat, element, new Point(-1, -1), 1, Emgu.CV.CvEnum.BorderType.Default, new MCvScalar(0, 0, 0));
// b 运算
//var element = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Cross,
// new Size(3, 3), new Point(-1, -1));
// CvInvoke.MorphologyEx(src, dstMat, Emgu.CV.CvEnum.MorphOp.Close, element,
// new Point(-1, -1), 1, Emgu.CV.CvEnum.BorderType.Default, new MCvScalar(0, 0, 0));
//高帽
//var element = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Cross, new Size(3, 3), new Point(-1, -1));
//CvInvoke.MorphologyEx(src, dstMat, Emgu.CV.CvEnum.MorphOp.Tophat, element, new Point(-1, -1), 1, Emgu.CV.CvEnum.BorderType.Default, new MCvScalar(0, 0, 0));
//var scr = new Mat(pngFilePath, ImreadModes.AnyColor);
//var dst = new Mat();
//CvInvoke.Laplacian(scr, dst, Emgu.CV.CvEnum.DepthType.Default, 1);
//二级化
//CvInvoke.Threshold(
// grayImage,
// threshImage,
// 180, //阀值
// 255, //最大值
// ThresholdType.ToZero);//二进制阈值化
// // //imageBox1.Image = grayImage;
// // //imageBox2.Image = threshImage;
CvInvoke.Threshold(
grayImage,
threshImage,
175, //阀值
255, //最大值
ThresholdType.Binary);
compressionFile = Path.Combine(outPutFolderPath, Guid.NewGuid().ToString() + ".png");
threshImage.Save(compressionFile);
}
return compressionFile;
}
public static Bitmap BitmapTo1Bpp(Bitmap img)
{
int w = img.Width;
int h = img.Height;
Bitmap bmp = new Bitmap(w, h, PixelFormat.Format1bppIndexed);
BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
byte[] scan = new byte[(w + 7) / 8];
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
if (x % 8 == 0) scan[x / 8] = 0;
Color c = img.GetPixel(x, y);
if (c.GetBrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
}
Marshal.Copy(scan, 0, (IntPtr)((long)data.Scan0 + data.Stride * y), scan.Length);
}
bmp.UnlockBits(data);
return bmp;
}
public static unsafe byte[] BitmapTo8Bpp(Bitmap colorBitmap)
{
byte[] result = null;
int Width = colorBitmap.Width;
int Height = colorBitmap.Height;
Bitmap grayscaleBitmap = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed);
grayscaleBitmap.SetResolution(colorBitmap.HorizontalResolution,
colorBitmap.VerticalResolution);
///////////////////////////////////////
// Set grayscale palette
///////////////////////////////////////
ColorPalette colorPalette = grayscaleBitmap.Palette;
for (int i = 0; i < colorPalette.Entries.Length; i++)
{
colorPalette.Entries[i] = Color.FromArgb(i, i, i);
}
grayscaleBitmap.Palette = colorPalette;
///////////////////////////////////////
// Set grayscale palette
///////////////////////////////////////
BitmapData bitmapData = grayscaleBitmap.LockBits(
new Rectangle(Point.Empty, grayscaleBitmap.Size),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
Byte* pPixel = (Byte*)bitmapData.Scan0;
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
Color clr = colorBitmap.GetPixel(x, y);
Byte byPixel = (byte)((30 * clr.R + 59 * clr.G + 11 * clr.B) / 100);
pPixel[x] = byPixel;
}
pPixel += bitmapData.Stride;
}
grayscaleBitmap.UnlockBits(bitmapData);
MemoryStream ms = new MemoryStream();
grayscaleBitmap.Save(ms, ImageFormat.Bmp);
result = ms.GetBuffer();
return result;
}
public static List<Bitmap> GetbitmapsFromPnglist(string[] lstFile)
{
List<Bitmap> result = new List<Bitmap>();
try
{
foreach (var tmpFile in lstFile)
{
Image image = Image.FromFile(tmpFile);
Bitmap bmp = new Bitmap(image);
result.Add(bmp);
}
}
catch (Exception ex)
{
throw ex;
}
return result;
}
public static List<Bitmap> GetbitmapsFromTifflist(string[] lstFile)
{
List<Bitmap> result = new List<Bitmap>();
try
{
foreach (var tmpFile in lstFile)
{
using (Image image = Image.FromFile(tmpFile))
{
int totalImage = image.GetFrameCount(FrameDimension.Page);
for (int i = 0; i < totalImage; i++)
{
image.SelectActiveFrame(FrameDimension.Page, i);
Bitmap bmp = new Bitmap(image);
result.Add(bmp);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
return result;
}
public static bool Jpegs2Tiff(List<Bitmap> bmps, string tiffSavePath, int quality = 15)
{
try
{
MemoryStream ms = new MemoryStream();
using (Tiff tif = Tiff.ClientOpen(@"in-memory", "w", ms, new TiffStream()))
{
foreach (var bmp in bmps)//
{
byte[] raster = GetImageRasterBytes(bmp, PixelFormat.Format24bppRgb);
tif.SetField(TiffTag.IMAGEWIDTH, bmp.Width);
tif.SetField(TiffTag.IMAGELENGTH, bmp.Height);
tif.SetField(TiffTag.COMPRESSION, Compression.JPEG);
tif.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
//tif.SetField(TiffTag.JPEGQUALITY, quality);
tif.SetField(TiffTag.JPEGQUALITY, quality);
tif.SetField(TiffTag.ROWSPERSTRIP, bmp.Height);
tif.SetField(TiffTag.XRESOLUTION, 90);
tif.SetField(TiffTag.YRESOLUTION, 90);
tif.SetField(TiffTag.BITSPERSAMPLE, 8);
tif.SetField(TiffTag.SAMPLESPERPIXEL, 3);
tif.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
int stride = raster.Length / bmp.Height;
ConvertSamples(raster, bmp.Width, bmp.Height);
for (int i = 0, offset = 0; i < bmp.Height; i++)
{
tif.WriteScanline(raster, offset, i, 0);
offset += stride;
}
tif.WriteDirectory();
}
System.IO.FileStream fs = new FileStream(tiffSavePath, FileMode.Create);
ms.Seek(0, SeekOrigin.Begin);
fs.Write(ms.ToArray(), 0, (int)ms.Length);
fs.Close();
return true;
}
}
catch (Exception ex)
{
throw ex;
}
}
public static bool Jpegs2Tiff(string[] bmps, string tiffSavePath, int quality = 15)
{
try
{
MemoryStream ms = new MemoryStream();
using (Tiff tif = Tiff.ClientOpen(@"in-memory", "w", ms, new TiffStream()))
{
Bitmap bmp = null;
foreach (var tmpFile in bmps)//
{
using (Image image = Image.FromFile(tmpFile))
{
int totalImage = image.GetFrameCount(FrameDimension.Page);
for (int i = 0; i < totalImage; i++)
{
image.SelectActiveFrame(FrameDimension.Page, i);
bmp = new Bitmap(image);
byte[] raster = GetImageRasterBytes(bmp, PixelFormat.Format24bppRgb);
tif.SetField(TiffTag.IMAGEWIDTH, bmp.Width);
tif.SetField(TiffTag.IMAGELENGTH, bmp.Height);
tif.SetField(TiffTag.COMPRESSION, Compression.JPEG);
tif.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
//tif.SetField(TiffTag.JPEGQUALITY, quality);
tif.SetField(TiffTag.JPEGQUALITY, quality);
tif.SetField(TiffTag.ROWSPERSTRIP, bmp.Height);
tif.SetField(TiffTag.XRESOLUTION, 90);
tif.SetField(TiffTag.YRESOLUTION, 90);
tif.SetField(TiffTag.BITSPERSAMPLE, 8);
tif.SetField(TiffTag.SAMPLESPERPIXEL, 3);
tif.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
int stride = raster.Length / bmp.Height;
ConvertSamples(raster, bmp.Width, bmp.Height);
for (int j = 0, offset = 0; j < bmp.Height; j++)
{
tif.WriteScanline(raster, offset, j, 0);
offset += stride;
}
tif.WriteDirectory();
}
}
}
System.IO.FileStream fs = new FileStream(tiffSavePath, FileMode.Create);
ms.Seek(0, SeekOrigin.Begin);
fs.Write(ms.ToArray(), 0, (int)ms.Length);
fs.Close();
return true;
}
}
catch (Exception ex)
{
throw ex;
}
}
private static MemoryStream ms1 = new MemoryStream();
private static Tiff tif = Tiff.ClientOpen(@"in-memory", "w", ms1, new TiffStream());
/// <summary>
/// tiff图片合成,一次合并一张
/// </summary>
/// <param name="index">图片id</param>
/// <param name="totalCount">图片数量</param>
/// <param name="tiffSavePath">tiff保存路径</param>
/// <param name="quality">压缩品质</param>
/// <returns></returns>
public static void Jpeg2Tiff(int index, int totalCount, string tiffSavePath, string fileName, int quality = 75)
{
try
{
string fileFullPath = Path.Combine(tiffSavePath, fileName);
Stopwatch sTotal = new Stopwatch();
sTotal.Start();
TimeSpan timeSpan = new TimeSpan();
//timeSpan.Id = index;
//Bitmap[] bmps = new Bitmap[1] {new Bitmap( @"C:\Users\zhuyr\Desktop\AutoFocus\" + $"{i}.bmp")};
Stopwatch sw = new Stopwatch();
sw.Start();
Bitmap bmp = new Bitmap(tiffSavePath + $"{index}.bmp");
sw.Stop();
//timeSpan.LoadTime = sw.ElapsedMilliseconds.ToString();
sw = new Stopwatch();
sw.Start();
byte[] raster = GetImageRasterBytes(bmp, PixelFormat.Format24bppRgb);
tif.SetField(TiffTag.IMAGEWIDTH, bmp.Width);
tif.SetField(TiffTag.IMAGELENGTH, bmp.Height);
tif.SetField(TiffTag.COMPRESSION, Compression.NONE);
tif.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB);
tif.SetField(TiffTag.JPEGQUALITY, quality);
tif.SetField(TiffTag.ROWSPERSTRIP, bmp.Height);
tif.SetField(TiffTag.XRESOLUTION, 90);
tif.SetField(TiffTag.YRESOLUTION, 90);
tif.SetField(TiffTag.BITSPERSAMPLE, 8);
tif.SetField(TiffTag.SAMPLESPERPIXEL, 3);
tif.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
int stride = raster.Length / bmp.Height;
ConvertSamples(raster, bmp.Width, bmp.Height);
for (int i = 0, offset = 0; i < bmp.Height; i++)
{
tif.WriteScanline(raster, offset, i, 0);
offset += stride;
}
tif.WriteDirectory();
sw.Stop();
//timeSpan.MergeTime = sw.ElapsedMilliseconds.ToString();
sw = new Stopwatch();
sw.Start();
if (totalCount == 1000)
{
if (index % 10 == 9)
{
System.IO.FileStream fs = new FileStream(fileFullPath, FileMode.Create);
ms1.Seek(0, SeekOrigin.Begin);
fs.Write(ms1.ToArray(), 0, (int)ms1.Length);
fs.Close();
sw.Stop();
}
}
else
{
System.IO.FileStream fs = new FileStream(fileFullPath, FileMode.Create);
ms1.Seek(0, SeekOrigin.Begin);
fs.Write(ms1.ToArray(), 0, (int)ms1.Length);
fs.Close();
sw.Stop();
}
//timeSpan.SaveTime = sw.ElapsedMilliseconds.ToString();
sTotal.Stop();
//timeSpan.TotalTime = sTotal.ElapsedMilliseconds.ToString();
//timeSpan.flag = true;
//return timeSpan;
}
catch (Exception ex)
{
//return null;
}
}
private static byte[] GetImageRasterBytes(Bitmap bmp, PixelFormat format)
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
byte[] bits = null;
try
{
BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, format);
bits = new byte[bmpdata.Stride * bmpdata.Height];
System.Runtime.InteropServices.Marshal.Copy(bmpdata.Scan0, bits, 0, bits.Length);
bmp.UnlockBits(bmpdata);
}
catch
{
return null;
}
return bits;
}
private static void ConvertSamples(byte[] data, int width, int height)
{
int stride = data.Length / height;
const int samplesPerPixel = 3;
for (int y = 0; y < height; y++)
{
int offset = stride * y;
int strideEnd = offset + width * samplesPerPixel;
for (int i = offset; i < strideEnd; i += samplesPerPixel)
{
byte temp = data[i + 2];
data[i + 2] = data[i];
data[i] = temp;
}
}
}
public static void GetTiffProperty(string fileName)
{
try
{
}
catch (Exception ex)
{
throw ex;
}
}
}
}