ビットマップの配列をTIFF形式のまったく新しいイメージに変換し、この新しいTIFFイメージのフレームとしてすべてのビットマップを追加するにはどうすればよいですか?
.NET 2.0を使用します。
最初のビットマップをImageオブジェクトに配置して開始します
Bitmap bitmap = (Bitmap)Image.FromFile(file);
ビットマップをtiffとしてメモリに保存します
MemoryStream byteStream = new MemoryStream();
bitmap.Save(byteStream, ImageFormat.Tiff);
Tiffを別のImageオブジェクトに入れます
Image tiff = Image.FromStream(byteStream)
エンコーダーを準備します。
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);
ファイルに保存:
tiff.Save(sOutFilePath, encoderInfo, encoderParams);
以降のページでは、エンコーダーを準備します。
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);
最後にファイルをフラッシュします。
EncoderParameter SaveEncodeParam = new EncoderParameter(
Encoder.SaveFlag, (long)EncoderValue.Flush);
EncoderParams = new EncoderParameters(1);
EncoderParams.Param[0] = SaveEncodeParam;
tiff.SaveAdd(EncoderParams);
これで開始できます。
Googleで少し検索した後、この投稿に出会いました。 a'b'c'd'e'f'g'h 'の投稿にあるコードを試しましたが、うまくいきませんでした。おそらく、私は何かを正しく行っていませんでした。
いずれにせよ、画像を複数ページのTIFFに保存する別の投稿を見つけました。投稿へのリンクは次のとおりです。 http://www.bobpowell.net/addframes.htm
また、ここに私のために働いたコードがあります。それはその投稿と同一でなければなりません。
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);
役立つトピック。情報をありがとう。 base64でエンコードされた文字列の配列からマルチページ画像をステッチする必要がありました。これは、このスレッドの情報に基づいてまとめたものです。私は明示的に指定された画像形式でメモリストリームを作成する必要がある理由をよく理解していませんが、これが機能することになりました。これに対処するより良い方法がある場合はお知らせください。ありがとう
/// <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);
}
}
ネクロマンシング
受け入れられた答えは少しあいまいです。
完全な動作コードは次のとおりです。
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;
}
}
標準形式のファイルの処理と作成に関しては、Microsoftの実績のファンではないため、ImageMagickを使用することをお勧めします。ImageMagickは、 MagickNet (注意、 http://midimick.com/magicknet/ には現在、スパイウェアのポップアップが表示されています。サイト所有者に警告しています)。
以下は、マルチTIFFファイルの分割操作です。文字列部分文字列関数のように機能します。画像の最初のインデックスはMasterBitMapになり、インデックスの最後までMasterBitmapにフレームを追加し続けます。
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;
}
}
}
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