Cannot save TIF file using GDI+

百般思念 提交于 2020-08-09 09:31:12

问题


I have a vb.net app that selects and loads a JPG file

 LoadedImage = Image.FromFile(InputImageName)

then attempts to save the file as a TIF using GDI+

 LoadedImage.Save(TIF_ImageName, ImageFormat.Tiff)

There are no syntax errors, but the save fails with

System.InvalidCastException was unhandled
Message=Conversion from string "System.Runtime.InteropServices.E" to type 'Integer' is not valid.

I have tried using a bitmap instead of image, no joy The image is large (9000x11000 pixels) Is this an encoderparams issue - perhaps there is no default?, and the available samples for that were for a bitonal image.

In the end, I will be generating new TIF Tags with location data, so this is an interim step in the development.


回答1:


Try with the ImageCodecInfo class, which provides means to control the codec parameters used to encode an Image format.

In GDI+, you can specify a really limited number of parameters. In practice, just the Compression method and the Quality level, which determines the compression level (0-100, where 0 is the maximum compression).

These parameters are assembled in a EncoderParameters array of EncoderParameter objects - used to specify the Encoder cathegory - before passing them to the Image.Save() overload that accepts the an ImageCodecInfo and EncoderParameters as arguments.

Sample method call:
Save a source image to a TIFF format, using the same DPI setting, compression level set to 50%. The image is saved as in 24bpp RGB Format. Modify as required.
The compression type is LZW.

Dim jpgImage As Image = Image.FromFile("ImageFile.jpg"), True)
SaveTiffImage(jpgImage, jpgImage.VerticalResolution, 50L, "DestinationFile.tif")
jpgImage.Dispose()

Codec initialization method:

Imports System.Drawing
Imports System.Drawing.Imaging
Imports ImageCodec = System.Drawing.Imaging.Encoder

Private Sub SaveTiffImage(image As Image, resolution As Single, compressionLevel As Long, fileName As String)
    resolution = Math.Max(72, Math.Min(2400, resolution))
    compressionLevel = Math.Max(0, Math.Min(100, compressionLevel))

    Using bitmap = New Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb)
        bitmap.SetResolution(resolution, resolution)
        Using g = Graphics.FromImage(bitmap)
            g.DrawImage(image, New Rectangle(Point.Empty, image.Size),
                               New Rectangle(Point.Empty, image.Size), GraphicsUnit.Pixel)
            Dim codec = ImageCodecInfo.GetImageEncoders().
                        FirstOrDefault(Function(enc) enc.FormatID = ImageFormat.Tiff.Guid)
            Dim qualityParam =
                New EncoderParameter(ImageCodec.Quality, compressionLevel)
            Dim compressionParam =
                New EncoderParameter(ImageCodec.Compression, EncoderValue.CompressionLZW)
            Using codecParms = New EncoderParameters(2)
                codecParms.Param(0) = qualityParam
                codecParms.Param(1) = compressionParam
                bitmap.Save(fileName, codec, codecParms)
            End Using
        End Using
    End Using
End Sub

C# version:

using System.Drawing;
using System.Drawing.Imaging;
using ImageCodec = System.Drawing.Imaging.Encoder;

private void SaveTiffImage(Image image, float resolution, long compressionLevel, string fileName)
{
    resolution = Math.Max(72, Math.Min(2400, resolution));
    compressionLevel = Math.Max(0, Math.Min(100, compressionLevel));

    using (var bitmap = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb))
    {
        bitmap.SetResolution(resolution, resolution);
        using (var g = Graphics.FromImage(bitmap))
        {
            g.DrawImage(image, new Rectangle(Point.Empty, image.Size), 
                               new Rectangle(Point.Empty, image.Size), GraphicsUnit.Pixel);
            var imageCodec = ImageCodecInfo.GetImageEncoders()
                                .FirstOrDefault(enc => enc.FormatID == ImageFormat.Tiff.Guid);
            if (imageCodec == null)
                throw new NotSupportedException("TIFF Conversion not suppoted", 
                      new NullReferenceException("TIFF Codec reference missing"));
            var qualityParam = 
                new EncoderParameter(ImageCodec.Quality, compressionLevel);
            var compressionParam = 
                new EncoderParameter(ImageCodec.Compression, (long)EncoderValue.CompressionLZW);
            using (var codecParms = new EncoderParameters(2))
            {
                codecParms.Param[0] = qualityParam;
                codecParms.Param[1] = compressionParam;
                bitmap.Save(fileName, imageCodec, codecParms);
            }
        }
    }
}


来源:https://stackoverflow.com/questions/56798086/cannot-save-tif-file-using-gdi

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!