gpt4 book ai didi

.net - 使用 .NET 创建带 JPEG 压缩的多页 TIFF

转载 作者:行者123 更新时间:2023-12-01 10:56:40 24 4
gpt4 key购买 nike

有没有办法使用 .NET 创建带有 JPEG 压缩的多页 TIFF?
我可以使用 LZW 压缩创建 TIFF,但文件非常大。看起来像 EncoderValue枚举(我用来设置压缩)甚至没有合适的成员。

最佳答案

你可以看看 >> this post , 我在这里解释了如何将现有的 JPEG 包装在一个简单的多页 TIFF 容器中。

但是还有其他各种可能性。 FreeImage.Net (freeimage.sourceforge.net) 是一个非常强大的库。您可以像这样创建一个简单的 JPEG 压缩 TIFF:

using FreeImageAPI;
// [...]
FIBITMAP image = FreeImage.Load(FREE_IMAGE_FORMAT.FIF_UNKNOWN, "filename", FREE_IMAGE_LOAD_FLAGS.DEFAULT);
FreeImage.Save(FREE_IMAGE_FORMAT.FIF_TIFF, image, "filename", FREE_IMAGE_SAVE_FLAGS.TIFF_JPEG)

创建多页 TIFF 有点棘手。据我所知,多页编辑只能在硬盘上进行。 (我听说在较新的版本中有另一种方法,所以也许可以尝试一下。)但是,您可以像这样使用 sth:
using System.IO;
using FreeImageAPI;

// [...]

public byte[] MergeTiffs(List<byte[]> tiffs)
{
byte[] multiPageTiff = null;
string tmpfile = "... chose any file name ...";
MemoryStream singleStream = null;
FIBITMAP fib = FIBITMAP.Zero;
FIMULTIBITMAP fmb = FIMULTIBITMAP.Zero;

using (singleStream = new MemoryStream(tiffs[0])
{
fib = FreeImage.LoadFromStream(singleStream);
FreeImage.SaveEx(fib, dateiname, FREE_IMAGE_FORMAT.FIF_TIFF, FREE_IMAGE_SAVE_FLAGS.TIFF_JPEG);
FreeImage.UnloadEx(ref fib);
}

fmb = FreeImage.OpenMultiBitmap(
FREE_IMAGE_FORMAT.FIF_TIFF,
tmpfile,
false,
false,
false,
FREE_IMAGE_LOAD_FLAGS.TIFF_JPEG);

for (int i = 1; i < tiffs.Count; i++)
{
using (singleStream = new MemoryStream(tiffs[i])
{
fib = FreeImage.LoadFromStream(singleStream);
FreeImage.AppendPage(fmb, fib);
}
}

FreeImage.CloseMultiBitmapEx(ref fmb);
multiPageTiff = File.ReadAllBytes(tmpfile);
File.Delete(tmpfile);

return file;
}

除此之外,我最近找到了一种简单的方法来将现有的 TIFF 与 合并。 LibTiff.Net (bitmiracle.com),无需更改其原始数据(因此您既不会降低质量也不会增加其大小)。可能有更简单的方法(也许你找到了),但我使用了以下代码(基于 this example):
using System.IO
using BitMiracle.LibTiff.Classic;

// [...]

/// <summary>
/// Merges multiple TIFFs into one multi-page TIFF
/// </summary>
/// <param name="tiffs">The TIFFs' raw data (can also be multi-page)</param>
/// <returns></returns>
public static byte[] MergeTiffs(List<byte[]> tiffs)
{
// the byteStream will contain the merged tiff's raw data
MemoryStream byteStream = new MemoryStream();
// create the output-TIFF (empty stream)
using (Tiff output = Tiff.ClientOpen("InMemory", "w", byteStream, new TiffStream()))
{
for (short i = 0; i < tiffs.Count; i++)
{
// provide input-TIFF as custom TiffStream, with byteStream (output-TIFF) as output
TiffStreamForBytes tiffStream = new TiffStreamForBytes(tiffs[i]);
using (Tiff input = Tiff.ClientOpen("bytes", "r", null, tiffStream))
{
// *** now copy all the TIFF-data: ***

// copy all directories (= all pages)
int numberOfDirectories = input.NumberOfDirectories();
for (short d = 0; d < numberOfDirectories; ++d)
{
// set this as the current directory (to work in)
input.SetDirectory(d);

// copy all tags
for (ushort t = ushort.MinValue; t < ushort.MaxValue; ++t)
{
TiffTag tag = (TiffTag)t;
FieldValue[] tagValue = input.GetField(tag);
if (tagValue != null)
output.GetTagMethods().SetField(output, tag, tagValue);
}

// copy all strips
int numberOfStrips = input.NumberOfStrips();
int stripSize = input.StripSize();
for (int s = 0; s < numberOfStrips; ++s)
{
// buffer for the current strip
byte[] stripData = new byte[stripSize];
// read strip from input image (not decompressed)
int length = input.ReadRawStrip(s, stripData, 0, stripData.Length);
// write strip to output image (uncompressed)
output.WriteRawStrip(s, stripData, 0, length);
}

// add the new directory to output image
output.WriteDirectory();
}
}
}
}
// return the new TIFF as byte array
return byteStream.ToArray();
}

/// <summary>
/// Custom read-only stream for byte buffer that can be used
/// with Tiff.ClientOpen method.
/// </summary>
private class TiffStreamForBytes : TiffStream
{
private byte[] m_bytes;
private int m_position;

public TiffStreamForBytes(byte[] bytes)
{
m_bytes = bytes;
m_position = 0;
}

public override int Read(object clientData, byte[] buffer, int offset, int count)
{
if ((m_position + count) > m_bytes.Length)
return -1;

Buffer.BlockCopy(m_bytes, m_position, buffer, offset, count);
m_position += count;
return count;
}

public override void Write(object clientData, byte[] buffer, int offset, int count)
{
throw new InvalidOperationException("This stream is read-only");
}

public override long Seek(object clientData, long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin:
if (offset > m_bytes.Length)
return -1;

m_position = (int)offset;
return m_position;

case SeekOrigin.Current:
if ((offset + m_position) > m_bytes.Length)
return -1;

m_position += (int)offset;
return m_position;

case SeekOrigin.End:
if ((m_bytes.Length - offset) < 0)
return -1;

m_position = (int)(m_bytes.Length - offset);
return m_position;
}

return -1;
}

public override void Close(object clientData)
{
// nothing to do
}

public override long Size(object clientData)
{
return m_bytes.Length;
}
}

关于.net - 使用 .NET 创建带 JPEG 压缩的多页 TIFF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14814254/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com