簡體   English   中英

將 bitmap (rgb) 與 TIFF (cmyk) 連接,而不將 cmyk 轉換為 rgb

[英]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 的質量,所以我認為最好不要進行任何轉換,保持原始並合並。 無論如何,這只是一個猜測,其他選項也可以考慮。 請問有人能解釋一下我的情況嗎?

請參閱下面從 cmyk 轉換為 rgb 前后的 tiff 圖像比較。 CMYK(左)和后來轉換為 RGB(右)的 TIFF 圖像的比較

我不知道 TIFF 格式的任何容量可以同時具有兩個不同的色彩空間。 由於您正在處理 CMYK,我認為這是您要保留的。

如果是這樣,這樣做的步驟是:

  1. 加載 CMYK 圖像 A(使用BitmapDecoder
  2. 加載 RGB 圖像 B(使用BitmapDecoder
  3. 使用所需的顏色配置文件將圖像 B 轉換為 CMYK(使用FormatConvertedBitmap
  4. 如果需要,確保圖像 B 的像素格式與 A 匹配(使用FormatConvertedBitmap
  5. 將 memory 中的兩者合成為字節數組(使用CopyPixels ,然后 memory 操作,然后從內存中新建 bitmap )
  6. 將合成保存到新的 CMYK TIFF 文件(使用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 以獲取原件。)

圖像 A(CMYK): 圖片 1 - CMYK、白色、深黑色

圖像 B (RGB): 圖像 B - RGB、白色、黑色

結果(CMYK): 圖像結果 - 完全保持 CMYK 的 RGB,RGB 改變。

要使兩張圖像重疊,一張圖像必須具有某種透明度的概念。 遮罩就是其中的一個示例,您可以在其中選擇特定的顏色值來表示“透明”。 遮罩的缺點是遮罩不能很好地處理混疊的源圖像。 為此,您會想要做一個 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);
}

示例圖像 B: RGB 疊加圖像

示例 output: CMYK 疊加輸出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM