[英]Concatenate a bitmap (rgb) with a TIFF (cmyk) without converting cmyk to rgb
我正在開發一個應用程序來連接 RGB 格式的 bitmap 圖像和 CMYK 格式的 TIFF。 我嘗試過使用 System.Drawing 和 System.Windows.Media 命名空間。
問題是兩個庫都嘗試在合並之前將我的 TIFF 圖像轉換為 RGB,這會導致圖像質量下降。
據我了解,他們總是在處理之前將圖像轉換為 RGB 的原因是因為這兩個庫是出於渲染意圖而這樣做的。
我不需要渲染任何東西,只需將兩張照片合並並保存到磁盤,僅此而已。
我應該怎么做才能實現我的目標? 顯然,我不想失去 TIFF 的質量,所以我認為最好不要進行任何轉換,保持原始並合並。 無論如何,這只是一個猜測,其他選項也可以考慮。 請問有人能解釋一下我的情況嗎?
我不知道 TIFF 格式的任何容量可以同時具有兩個不同的色彩空間。 由於您正在處理 CMYK,我認為這是您要保留的。
如果是這樣,這樣做的步驟是:
BitmapDecoder
)BitmapDecoder
)FormatConvertedBitmap
)FormatConvertedBitmap
)CopyPixels
,然后 memory 操作,然后從內存中新建 bitmap )TiffBitmapEncoder
)WIC (System.Media)應該可以做到這一點。
這樣做的一個例子( github )可以寫成:
BitmapFrame LoadTiff(string filename)
{
using (var rs = File.OpenRead(filename))
{
return BitmapDecoder.Create(rs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad).Frames[0];
}
}
// Load, validate A
var imageA = LoadTiff("CMYK.tif");
if (imageA.Format != PixelFormats.Cmyk32)
{
throw new InvalidOperationException("imageA is not CMYK");
}
// Load, validate, convert B
var imageB = LoadTiff("RGB.tif");
if (imageB.PixelHeight != imageA.PixelHeight)
{
throw new InvalidOperationException("Image B is not the same height as image A");
}
var imageBCmyk = new FormatConvertedBitmap(imageB, imageA.Format, null, 0d);
// Merge
int width = imageA.PixelWidth + imageB.PixelWidth,
height = imageA.PixelHeight,
bytesPerPixel = imageA.Format.BitsPerPixel / 8,
stride = width * bytesPerPixel;
var buffer = new byte[stride * height];
imageA.CopyPixels(buffer, stride, 0);
imageBCmyk.CopyPixels(buffer, stride, imageA.PixelWidth * bytesPerPixel);
var result = BitmapSource.Create(width, height, imageA.DpiX, imageA.DpiY, imageA.Format, null, buffer, stride);
// save to new file
using (var ws = File.Create("out.tif"))
{
var tiffEncoder = new TiffBitmapEncoder();
tiffEncoder.Frames.Add(BitmapFrame.Create(result));
tiffEncoder.Save(ws);
}
它保持 CMYK 圖像的顏色准確性,並使用系統顏色配置文件轉換 RGB。 這可以在 Photoshop 中進行驗證,顯示每個字母和豐富的黑色都保持了它們的原始值。 (請注意,imgur 確實轉換為具有可疑顏色處理的 png - 檢查 github 以獲取原件。)
要使兩張圖像重疊,一張圖像必須具有某種透明度的概念。 遮罩就是其中的一個示例,您可以在其中選擇特定的顏色值來表示“透明”。 遮罩的缺點是遮罩不能很好地處理混疊的源圖像。 為此,您會想要做一個 Alpha 通道 - 但跨色彩空間混合將具有挑戰性。 ( Github )
// Load, validate A
var imageA = LoadTiff("CMYK.tif");
if (imageA.Format != PixelFormats.Cmyk32)
{
throw new InvalidOperationException("imageA is not CMYK");
}
// Load, validate, convert B
var imageB = LoadTiff("RGBOverlay.tif");
if (imageB.PixelHeight != imageA.PixelHeight
|| imageB.PixelWidth != imageA.PixelWidth)
{
throw new InvalidOperationException("Image B is not the same size as image A");
}
var imageBBGRA = new FormatConvertedBitmap(imageB, PixelFormats.Bgra32, null, 0d);
var imageBCmyk = new FormatConvertedBitmap(imageB, imageA.Format, null, 0d);
// Merge
int width = imageA.PixelWidth, height = imageA.PixelHeight;
var stride = width * (imageA.Format.BitsPerPixel / 8);
var bufferA = new uint[width * height];
var bufferB = new uint[width * height];
var maskBuffer = new uint[width * height];
imageA.CopyPixels(bufferA, stride, 0);
imageBBGRA.CopyPixels(maskBuffer, stride, 0);
imageBCmyk.CopyPixels(bufferB, stride, 0);
for (int i = 0; i < bufferA.Length; i++)
{
// set pixel in bufferA to the value from bufferB if mask is not white
if (maskBuffer[i] != 0xffffffff)
{
bufferA[i] = bufferB[i];
}
}
var result = BitmapSource.Create(width, height, imageA.DpiX, imageA.DpiY, imageA.Format, null, bufferA, stride);
// save to new file
using (var ws = File.Create("out_overlay.tif"))
{
var tiffEncoder = new TiffBitmapEncoder();
tiffEncoder.Frames.Add(BitmapFrame.Create(result));
tiffEncoder.Save(ws);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.