Convertir bitmaps à une image TIFF multipages dans .NET 2.0
Question
Comment convertir un tableau de bitmaps dans une toute nouvelle image de format TIFF, en ajoutant tous les bitmaps en tant que cadres dans cette nouvelle image tiff?
2,0 en utilisant .NET.
La solution
Commencez par le premier bitmap en le plaçant dans un objet image
Bitmap bitmap = (Bitmap)Image.FromFile(file);
Enregistrer le bitmap dans la mémoire au format TIFF
MemoryStream byteStream = new MemoryStream();
bitmap.Save(byteStream, ImageFormat.Tiff);
Mettre Tiff dans un autre objet Image
Image tiff = Image.FromStream(byteStream)
Préparer les codeurs:
var encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
EncoderParameters encoderParams = new EncoderParameters(2);
encoderParams.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionNone);
encoderParams.Param[1] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
Enregistrer dans le fichier:
tiff.Save(sOutFilePath, encoderInfo, encoderParams);
Pour les pages suivantes, préparer les codeurs:
EncoderParameters EncoderParams = new EncoderParameters(2);
EncoderParameter SaveEncodeParam = new EncoderParameter(
Encoder.SaveFlag,
(long)EncoderValue.FrameDimensionPage);
EncoderParameter CompressionEncodeParam = new EncoderParameter(
Encoder.Compression, (long)EncoderValue.CompressionNone);
EncoderParams.Param[0] = CompressionEncodeParam;
EncoderParams.Param[1] = SaveEncodeParam;
tiff.SaveAdd(/* next image as tiff - do the same as above with memory */, EncoderParams);
Enfin vider le fichier:
EncoderParameter SaveEncodeParam = new EncoderParameter(
Encoder.SaveFlag, (long)EncoderValue.Flush);
EncoderParams = new EncoderParameters(1);
EncoderParams.Param[0] = SaveEncodeParam;
tiff.SaveAdd(EncoderParams);
Cela devrait vous aider à démarrer.
Autres conseils
suis tombé sur ce poste après un peu de recherche sur Google. J'ai essayé le code qui était dans le poste par a'b'c'd'e'f'g'h », mais cela ne fonctionne pas pour moi. Peut-être, je ne faisais pas quelque chose correctement.
Dans tous les cas, j'ai trouvé un autre poste qui a sauvé des images à plusieurs tiff page. Voici le lien vers le message: http://www.bobpowell.net/addframes.htm
En outre, voici le code qui a fonctionné pour moi. Il doit être identique à ce poste.
Encoder encoder = Encoder.SaveFlag;
ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);
// Save the first frame of the multi page tiff
Bitmap firstImage = (Bitmap) _scannedPages[0].RawContent;
firstImage.Save(fileName, encoderInfo, encoderParameters);
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionPage);
// Add the remaining images to the tiff
for (int i = 1; i < _scannedPages.Count; i++)
{
Bitmap img = (Bitmap) _scannedPages[i].RawContent;
firstImage.SaveAdd(img, encoderParameters);
}
// Close out the file
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush);
firstImage.SaveAdd(encoderParameters);
sujet utile. Merci pour l'info. J'ai eu besoin de piquer une image multipage à partir d'un tableau de chaînes codées en base64. C'est ce que je mis en place sur la base des informations contenues dans ce fil. Je nai assez underststand pourquoi je dois créer un flux de mémoire avec le format d'image spécifié explicitement, mais c'est ce qui a fini le traitement, s'il y a une meilleure façon de traiter cette s'il vous plaît laissez-moi savoir. merci
/// <summary>
/// Takes in an array of base64 encoded strings and creates a multipage tiff.
/// </summary>
/// <param name="sOutFile">file to be generated</param>
/// <param name="pagesbase64Array"></param>
private void SaevAsMultiPageTiff(string sOutFile, string[] pagesbase64Array)
{
System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.SaveFlag;
ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);
Bitmap firstImage = null;
try
{
using (MemoryStream ms1 = new MemoryStream())
{
using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(pagesbase64Array[0])))
{
Image.FromStream(ms).Save(ms1, ImageFormat.Tiff);
firstImage = (Bitmap)Image.FromStream(ms1);
}
// Save the first frame of the multi page tiff
firstImage.Save(sOutFile, encoderInfo, encoderParameters); //throws Generic GDI+ error if the memory streams are not open when this is called
}
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionPage);
Bitmap imagePage;
// Add the remining images to the tiff
for (int i = 1; i < pagesbase64Array.Length; i++)
{
using (MemoryStream ms1 = new MemoryStream())
{
using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(pagesbase64Array[i])))
{
Image.FromStream(ms).Save(ms1, ImageFormat.Tiff);
imagePage = (Bitmap)Image.FromStream(ms1);
}
firstImage.SaveAdd(imagePage, encoderParameters); //throws Generic GDI+ error if the memory streams are not open when this is called
}
}
}
catch (Exception)
{
//ensure the errors are not missed while allowing for flush in finally block so files dont get locked up.
throw;
}
finally
{
// Close out the file
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush);
firstImage.SaveAdd(encoderParameters);
}
}
Ne pas être fan de la feuille de route de Microsoft en matière de manipulation et la création de fichiers de formats normalisés, je suggère d'utiliser ImageMagick, disponible comme une bibliothèque .Net sous forme de MagickNet (attention, http: // midimick.com/magicknet/ dispose actuellement d'un pop-up de logiciels espions, j'ai alerté le propriétaire du site).
Necromancing
La réponse acceptée est un peu vague.
Voici le code complet de travail:
public class MultiPageTiff
{
private static System.Drawing.Imaging.ImageCodecInfo GetEncoderInfo(string mimeType)
{
System.Drawing.Imaging.ImageCodecInfo[] encoders =
System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
if (encoders != null)
{
for (int i = 0; i < encoders.Length; i++)
{
if (encoders[i].MimeType == mimeType)
{
return encoders[i];
} // End if (encoders[i].MimeType == mimeType)
} // Next i
} // End if (encoders != null)
return null;
} // End Function GetEncoderInfo
public static System.Drawing.Image Generate(string[] filez)
{
System.Drawing.Image multiPageFile = null;
byte[] ba = null;
System.Drawing.Imaging.ImageCodecInfo tiffCodec = GetEncoderInfo("image/tiff");
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
for (int i = 0; i < filez.Length; ++i)
{
using (System.Drawing.Image inputImage = System.Drawing.Image.FromFile(filez[i]))
{
using (System.IO.MemoryStream byteStream = new System.IO.MemoryStream())
{
inputImage.Save(byteStream, System.Drawing.Imaging.ImageFormat.Tiff);
if (i == 0)
{
multiPageFile = System.Drawing.Image.FromStream(byteStream);
multiPageFile = SaveImages(tiffCodec, ms, multiPageFile, null);
}
else
{
using (System.Drawing.Image tiffImage = System.Drawing.Image.FromStream(byteStream))
{
multiPageFile = SaveImages(tiffCodec, ms, tiffImage, multiPageFile);
} // End Using tiffImage
}
} // End Using byteStream
} // End Using inputImage
} // Next i
ba = ms.ToArray();
} // End Using ms
System.IO.File.WriteAllBytes(@"d:\mytiff.tiff", ba);
//if (multiPageFile != null)
//{
// multiPageFile.Dispose();
// multiPageFile = null;
//}
return multiPageFile;
}
private static System.Drawing.Image SaveImages(
System.Drawing.Imaging.ImageCodecInfo tiffCodec
, System.IO.MemoryStream outputStream
, System.Drawing.Image tiffImage, System.Drawing.Image firstImage)
{
using (System.Drawing.Imaging.EncoderParameters encParameters =
new System.Drawing.Imaging.EncoderParameters(3))
{
if (firstImage == null)
{
encParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(
System.Drawing.Imaging.Encoder.SaveFlag
, (long)System.Drawing.Imaging.EncoderValue.MultiFrame // 18L
);
}
else
{
encParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(
System.Drawing.Imaging.Encoder.SaveFlag
, (long)System.Drawing.Imaging.EncoderValue.FrameDimensionPage // 23L
);
}
encParameters.Param[1] = new System.Drawing.Imaging.EncoderParameter(
System.Drawing.Imaging.Encoder.ColorDepth, 24L
);
encParameters.Param[2] = new System.Drawing.Imaging.EncoderParameter(
System.Drawing.Imaging.Encoder.Compression
, (long)System.Drawing.Imaging.EncoderValue.CompressionLZW
);
if (firstImage == null)
{
firstImage = tiffImage;
((System.Drawing.Bitmap)tiffImage).SetResolution(96, 96);
firstImage.Save(outputStream, tiffCodec, encParameters);
}
else
{
((System.Drawing.Bitmap)tiffImage).SetResolution(96, 96);
firstImage.SaveAdd(tiffImage, encParameters);
}
if (encParameters.Param[0] != null)
encParameters.Param[0].Dispose();
if (encParameters.Param[1] != null)
encParameters.Param[1].Dispose();
if (encParameters.Param[2] != null)
encParameters.Param[2].Dispose();
} // End Using encParameters
return firstImage;
}
}
Voici l'opération de scission de fichier multi-tiff. Il fonctionne comme la fonction de sous-chaîne de chaîne. Le premier indice de l'image sera votre MasterBitMap et vous continuer à ajouter à l'image MasterBitmap jusqu'à la fin de l'indice.
public void SaveMultiFrameTiff(int start, int end)
{
string outputFileName = "out.TIF";
string inputFileName = "input.TIF";
try
{
Bitmap MasterBitmap = new Bitmap(inputFileName ); //Start page of document(master)
Image imageAdd = Image.FromFile(inputFileName ); //Frame Image that will be added to the master
Guid guid = imageAdd.FrameDimensionsList[0]; //GUID
FrameDimension dimension = new FrameDimension(guid);
// start index cannot be less than 0 and cannot be greater than frame count
if (start < 1 || end > MasterBitmap.GetFrameCount(dimension)) { return; }
EncoderParameters ep = new EncoderParameters(1);
//Get Image Codec Information
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo codecInfo = codecs[3]; //image/tiff
//MultiFrame Encoding format
EncoderParameter epMultiFrame = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
ep.Param[0] = epMultiFrame;
MasterBitmap.SelectActiveFrame(dimension, start - 1);
MasterBitmap.Save(outputFileName, codecInfo, ep);//create master document
//FrameDimensionPage Encoding format
EncoderParameter epFrameDimensionPage = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
ep.Param[0] = epFrameDimensionPage;
for (int i = start; i < end; i++)
{
imageAdd.SelectActiveFrame(dimension, i);//select next frame
MasterBitmap.SaveAdd(new Bitmap(imageAdd), ep);//add it to the master
}
//Flush Encoding format
EncoderParameter epFlush = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.Flush);
ep.Param[0] = epFlush;
MasterBitmap.SaveAdd(ep); //flush the file
}
catch (Exception ex)
{
throw ex;
}
}
}
Voici comment faire en vb.net:
Imports System.Drawing.Imaging
Sub CreateTiff(sOutTiffFile As String, sInFile1 As String, sInFile2 As String)
Dim bitmap As Bitmap = Image.FromFile(sInFile1)
Dim byteStream As MemoryStream = New MemoryStream()
bitmap.Save(byteStream, System.Drawing.Imaging.ImageFormat.Tiff)
Dim tiff As Image = Image.FromStream(byteStream)
Dim oParams As EncoderParameters = New EncoderParameters(2)
oParams.Param(0) = New EncoderParameter(Imaging.Encoder.Compression, EncoderValue.CompressionCCITT4)
oParams.Param(1) = New EncoderParameter(Imaging.Encoder.SaveFlag, EncoderValue.MultiFrame)
tiff.Save(sOutTiffFile, GetEncoderInfo("image/tiff"), oParams)
'Next Page
Dim bitmap2 As Bitmap = Image.FromFile(sInFile2)
oParams.Param(1) = New EncoderParameter(Imaging.Encoder.SaveFlag, EncoderValue.FrameDimensionPage)
tiff.SaveAdd(bitmap2, oParams)
'Flush
Dim oFlushParams As EncoderParameters = New EncoderParameters(1)
oFlushParams.Param(0) = New EncoderParameter(Imaging.Encoder.SaveFlag, EncoderValue.Flush)
tiff.SaveAdd(oFlushParams)
End Sub
Private Function GetEncoderInfo(mimeType As String) As System.Drawing.Imaging.ImageCodecInfo
Dim encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
For i As Integer = 0 To encoders.Length - 1
If encoders(i).MimeType = mimeType Then
Return encoders(i)
End If
Next
Return Nothing
End Function