将不同的图片格式(jpg、gif、png等)转换为TIFF格式。

21

我正在研究通过OCR从图像中读取文本的技术。它只支持TIFF格式的图像。

因此,我需要将其他格式转换为TIFF格式。这可行吗?请提供一些参考资料来帮助我。


@l--''''''---------'''''''''''' 这是一个不同的问题。 - Reza Aghaei
如@Reza所说,通过将pdf添加到您制作的列表中,使得这成为了一个完全不同的问题。pdf是矢量图形格式,而其他格式(包括目标tiff)是位图图形格式。因此,我会回滚那个编辑。 - mkl
@l--''''''---------'''''''''''' 您的问题是如何将多个文件转换为一个tiff文件?所以我理解您需要将图像1、2、3、4合并成一个tiff文件,是这样吗?另一个问题是,您还需要进行pdf转换,是这样吗?因此,我有解决方案来回答您的问题。 - Maytham Fahmi
@maytham-ɯɐɥʇʎɐɯ 我需要能够将图像和PDF文件合并成一个TIFF文件。 - Alex Gordon
@l--''''''---------'''''''''''' 你是否接受基于亚马逊网络服务(AWS)的解决方案? - Taterhead
6个回答

23
如果您在.NET中创建一个Image对象,您可以将其保存为TIFF格式。这是您可以使用的众多ImageFormat之一。
示例:
var png = Image.FromFile("some.png");
png.Save("a.tiff", ImageFormat.Tiff);

你需要在项目中包含System.Drawing程序集。该程序集将为您提供许多图像处理功能。希望这有所帮助。


我已经在Ms Paint中将tiff图像编辑为gif图像。这会导致错误吗? - user1509
png.Save 是一个 void 方法,因此不能将 Tiff 设置为其返回值。 - argyle
这会使图像文件大小增加太多,从仅有的748 KB(image.jpg)到4.305 KB(image.tif)。是否可能在不增加图像大小或至少不增加太多的情况下进行此转换?我有一个要求,即图像不应大于200 KB,因此我正在尝试将TIFF转换为JPG以减小大小,然后再将其转换回TIFF。转换后,我计划执行一些更多的大小缩减步骤,但首先我需要能够进行此转换。 - Ulysses Alves
Image::Save 有多个重载函数,可以让你针对编码器参数进行具体设置。我不是 TIFF 格式的专家,但你可以在这里找到一些有用的细节:https://msdn.microsoft.com/zh-cn/library/system.drawing.imaging.encoderparameter(v=vs.110).aspx - Jacob
还有潜在的有用资源:https://learn.microsoft.com/zh-cn/dotnet/framework/winforms/advanced/using-image-encoders-and-decoders-in-managed-gdi - Jacob
显示剩余2条评论

14

简介:

  1. 这篇回答涵盖了一个赏金问题:我们如何将多个文件转换为一个tiff?例如,假设我们有pdf、jpeg和png文件,我想把它们合成一个tiff文件?
  2. 在本答案中,我使用了.net实现的ImageMagick图像处理工具和Ghostscript,以帮助读取AI/EPS/PDF/PS文件,使其能够转换成图像文件。两者都是可靠的官方来源。
  3. 在回答这个问题后,我收到了一些额外的电子邮件提问其他合并选项,因此我扩展了我的答案。

我认为您需要以下两个步骤来达到目标:

  1. 安装所需的pdf转换工具
  2. 从源中获取所有图像(包括pdf格式的文件)并将它们合并到一个tiff文件中。

1. 安装pdf转换工具:

如果您只打算转换其他图像格式的文件,请跳过第1步。

要将pdf转换为任何图像格式,我们需要一个可以读取pdf文件的库,还需要一个将其转换为图像类型的工具。为此,我们需要安装Ghostscript(GNU Affero通用公共许可证)。

接下来,我们需要安装在Visual Studio中使用的Magick.NET库,可以通过nuget链接进行下载。

到这里已经很好了。

2. 代码部分

第二步也是最后一步,我们需要从文件夹位置读取文件(png、jpg、bmp、pdf等),并将每个文件添加到MagickImageCollection中,然后我们有几个选项可以合并使用AppendHorizontallyAppendVerticallyMontage 或 多页的tiff。ImageMagick有大量的功能,如调整大小,分辨率等,这只是演示合并功能的例子:

public static void MergeImage(string src, string dest, MergeType type = MergeType.MultiplePage)
{
    var files = new DirectoryInfo(src).GetFiles();

    using (var images = new MagickImageCollection())
    {
        foreach (var file in files)
        {
            var image = new MagickImage(file)
            {
                Format = MagickFormat.Tif,
                Depth = 8,
            };
            images.Add(image);
        }

        switch (type)
        {
            case MergeType.Vertical:
                using (var result = images.AppendVertically())
                {
                    result.AdaptiveResize(new MagickGeometry(){Height = 600, Width = 800});
                    result.Write(dest);
                }
                break;
            case MergeType.Horizontal:
                using (var result = images.AppendHorizontally())
                {
                    result.AdaptiveResize(new MagickGeometry(){Height = 600, Width = 800});
                    result.Write(dest);
                }
                break;
            case MergeType.Montage:
                var settings = new MontageSettings
                {
                    BackgroundColor = new MagickColor("#FFF"),
                    Geometry = new MagickGeometry("1x1<")
                };

                using (var result = images.Montage(settings))
                {
                    result.Write(dest);
                }
                break;
            case MergeType.MultiplePage:
                images.Write(dest);
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(type), type, "Un-support choice");
        }

        images.Dispose();
    }
}

public enum MergeType
{
    MultiplePage,
    Vertical,
    Horizontal,
    Montage
}

运行代码

public static void Main(string[] args)
{
    var src = @"C:\temp\Images";
    var dest1 = @"C:\temp\Output\MultiplePage.tiff";
    var dest2 = @"C:\temp\Output\Vertical.tiff";
    var dest3 = @"C:\temp\Output\Horizontal.tiff";
    var dest4 = @"C:\temp\Output\Montage.tiff";

    MergeImage(src, dest1);
    MergeImage(src, dest2, MergeType.Vertical);
    MergeImage(src, dest3, MergeType.Horizontal);
    MergeImage(src, dest4, MergeType.Montage);
}

这里有4个输入文件在C:\temp\Images目录下:

enter image description here enter image description here enter image description here enter image description here

运行代码后,我们在C:\temp\Output下得到了4个新文件,分别如下:

enter image description here 4页多页Tiff

enter image description here 4张图片垂直合并

enter image description here 4张图片水平合并

enter image description here 4张图片拼贴合并

最后说明:

  1. 使用System.Drawing;和System.Drawing.Imaging;可以将多个图像合并成Tiff,而不需要使用ImageMagick。但将PDF转换为图像需要第三方的转换库或工具,因此我使用C#的Ghostscript和ImageMagick。
  2. ImageMagick有许多功能,因此您可以更改分辨率、输出文件的大小等。它是一个公认的库。

免责声明:本答案的一部分摘自我的个人网站https://itbackyard.com/how-to-convert-ai-eps-pdf-ps-to-image-file/,并提供了源代码到Github。


ImageMagick可以将输出合并成一个多页tiff,而无需先合并输入图像。请参见我的答案。 - fmw42
我看到了那个点赞,问题是OP要求C#代码,据我所知ImageMagick功能可在不同的语言中实现,包括C#。我的观点是改变代码使其成为可能,而不是合并,制作多个tiff页面。但根据我从OP的评论中理解,他需要将它们合并成一个tiff文件,而不是多个页面。如果是多页,我会更新我的答案,但我也在等待OP的一些评论。这不会改变OP需要使用imageMagick将pdf转换为图像的事实。 - Maytham Fahmi

4
将tif格式的图像进行转换。在下面的示例中,将图像转换并设置为文本框。在文本框中查看图像是(.tif格式)。此源代码可正常工作。
private void btn_Convert(object sender, EventArgs e)
    {
        string newName = System.IO.Path.GetFileNameWithoutExtension(CurrentFile);
        newName = newName + ".tif";
        try
        {
            img.Save(newName, ImageFormat.Tiff);
        }
        catch (Exception ex)
        {
            string error = ee.Message.ToString();
            MessageBox.Show(MessageBoxIcon.Error);

        }
        textBox2.Text = System.IO.Path.GetFullPath(newName.ToString());
    }

这个回答如何回答问题?它能将PDF转换吗?它是否像OP所要求的那样合并文件? - Maytham Fahmi
使用PDF转图像转换器SDK将PDF转换为TIFF。 - Bibin
这正是问题所在,楼主想要将多个文件包括PDF转换为一个TIFF文件。 - Maytham Fahmi
创建PQScan.PDFToImage.PDFDocument对象的实例。加载本地PDF文件。获取总页数。将PDF文件页转换为图像。将图像保存为tiff图像文件类型。 - Bibin
赏金问题:我们如何将多个文件转换为一个tiff文件?例如,假设我们有pdf、jpeg、png文件,我想将它们合并成一个tiff文件。 - Maytham Fahmi

3

我已经测试了jpg、bmp、png和gif格式,可以用于单页和多页tiff文件的创建。请传入完整的文件路径。希望这能帮助到某些人。(摘自MSDN)

public static string[] ConvertJpegToTiff(string[] fileNames, bool isMultipage)
    {
        EncoderParameters encoderParams = new EncoderParameters(1);
        ImageCodecInfo tiffCodecInfo = ImageCodecInfo.GetImageEncoders()
            .First(ie => ie.MimeType == "image/tiff");

        string[] tiffPaths = null;
        if (isMultipage)
        {
            tiffPaths = new string[1];
            System.Drawing.Image tiffImg = null;
            try
            {
                for (int i = 0; i < fileNames.Length; i++)
                {
                    if (i == 0)
                    {
                        tiffPaths[i] = String.Format("{0}\\{1}.tif",
                            Path.GetDirectoryName(fileNames[i]),
                            Path.GetFileNameWithoutExtension(fileNames[i]));

                        // Initialize the first frame of multipage tiff.
                        tiffImg = System.Drawing.Image.FromFile(fileNames[i]);
                        encoderParams.Param[0] = new EncoderParameter(
                            System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
                        tiffImg.Save(tiffPaths[i], tiffCodecInfo, encoderParams);
                    }
                    else
                    {
                        // Add additional frames.
                        encoderParams.Param[0] = new EncoderParameter(
                            System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
                        using (System.Drawing.Image frame = System.Drawing.Image.FromFile(fileNames[i]))
                        {
                            tiffImg.SaveAdd(frame, encoderParams);
                        }
                    }

                    if (i == fileNames.Length - 1)
                    {
                        // When it is the last frame, flush the resources and closing.
                        encoderParams.Param[0] = new EncoderParameter(
                            System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.Flush);
                        tiffImg.SaveAdd(encoderParams);
                    }
                }
            }
            finally
            {
                if (tiffImg != null)
                {
                    tiffImg.Dispose();
                    tiffImg = null;
                }
            }
        }
        else
        {
            tiffPaths = new string[fileNames.Length];

            for (int i = 0; i < fileNames.Length; i++)
            {
                tiffPaths[i] = String.Format("{0}\\{1}.tif",
                    Path.GetDirectoryName(fileNames[i]),
                    Path.GetFileNameWithoutExtension(fileNames[i]));

                // Save as individual tiff files.
                using (System.Drawing.Image tiffImg = System.Drawing.Image.FromFile(fileNames[i]))
                {
                    tiffImg.Save(tiffPaths[i], ImageFormat.Tiff);
                }
            }
        }

        return tiffPaths;
    }

如果文件是一个 Stream 会怎样呢? - Alex Gordon
它可以转换PDF文件吗? - Maytham Fahmi

3
ImageMagick命令行可以轻松完成此操作。它在大多数Linux系统上提供,并且也可用于Mac或Windows。请参见https://imagemagick.org/script/download.php
convert image.suffix -compress XXX image.tiff

或者您可以使用
处理整个文件夹的文件。
mogrify -format tiff -path path/to/output_directory *


ImageMagick支持将多个图像合并为多页TIFF。这些图像可以是不同类型的,甚至包括PDF。
convert image1.suffix1 image2.suffix2 ... -compress XXX imageN.suffixN output.tiff


您可以选择多种压缩格式或不进行压缩。

请参见

https://imagemagick.org/script/command-line-processing.php

https://imagemagick.org/Usage/basics/

https://imagemagick.org/Usage/basics/#mogrify

https://imagemagick.org/script/command-line-options.php#compress


或者您可以使用Magick.Net进行C#接口。请参见https://github.com/dlemstra/Magick.NET

主要的ImageMagick页面在https://imagemagick.org

支持的格式在https://imagemagick.org/script/formats.php中列出。

您可以轻松地处理图像,将它们调整大小,转换为灰度,过滤(锐化),阈值等,都在同一命令行中。

请参见

https://imagemagick.org/Usage/

https://imagemagick.org/Usage/reference.html


2
这是我将上传到网站的图像转换的方法。我对其进行了更改,以输出Tiff文件。该方法输入和输出字节数组,因此可以轻松地在各种情况下使用。但您可以轻松修改它。"最初的回答"
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

public byte[] ConvertImageToTiff(byte[] SourceImage)
{
    //create a new byte array
    byte[] bin = new byte[0];

    //check if there is data
    if (SourceImage == null || SourceImage.Length == 0)
    {
        return bin;
    }

    //convert the byte array to a bitmap
    Bitmap NewImage;
    using (MemoryStream ms = new MemoryStream(SourceImage))
    {
        NewImage = new Bitmap(ms);
    }

    //set some properties
    Bitmap TempImage = new Bitmap(NewImage.Width, NewImage.Height);
    using (Graphics g = Graphics.FromImage(TempImage))
    {
        g.CompositingMode = CompositingMode.SourceCopy;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.PixelOffsetMode = PixelOffsetMode.HighQuality;
        g.DrawImage(NewImage, 0, 0, NewImage.Width, NewImage.Height);
    }
    NewImage = TempImage;

    //save the image to a stream
    using (MemoryStream ms = new MemoryStream())
    {
        EncoderParameters encoderParameters = new EncoderParameters(1);
        encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 80L);

        NewImage.Save(ms, GetEncoderInfo("image/tiff"), encoderParameters);
        bin = ms.ToArray();
    }

    //cleanup
    NewImage.Dispose();
    TempImage.Dispose();

    //return data
    return bin;
}


//get the correct encoder info
public ImageCodecInfo GetEncoderInfo(string MimeType)
{
    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
    for (int j = 0; j < encoders.Length; ++j)
    {
        if (encoders[j].MimeType.ToLower() == MimeType.ToLower())
            return encoders[j];
    }
    return null;
}

To test

var oldImage = File.ReadAllBytes(Server.MapPath("OldImage.jpg"));
var newImage = ConvertImageToTiff(oldImage);
File.WriteAllBytes(Server.MapPath("NewImage.tiff"), newImage);

它是否像OP所要求的那样将PDF转换为图像? - Maytham Fahmi
@maytham-ɯɐɥʇʎɐɯ 不行,因为 OP 正在要求将其转换为 TIFF 格式。他已经有 OCR 软件了。 - VDWWD
1
根据我的理解,这是一个旧问题,所以悬赏问题要求回答以下问题: 寻找可信和/或官方来源的答案。 我们如何将多个文件转换为1个tiff?例如,假设有pdf、jpeg、png文件,我想将它们合并成1个tiff文件? - Maytham Fahmi
@maytham-ɯɐɥʇʎɐɯ,我认为你是对的。OP正在询问TIFF相关问题,但悬赏者想要将多个图像和PDF合并成一个文件。我没有看到评论...如果可以的话,我会尝试创建一个解决方案。 - VDWWD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接