簡體   English   中英

為什么 BitmapData Stride 有交替符號?

[英]Why BitmapData Stride have alternating sign?

我有以下代碼

        var rect = new Rectangle(x, y, w, h);
        BitmapData data = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
        BitmapSource cropppedImage;
        if (data.Stride < 0)
        {
            cropppedImage = BitmapSource.Create(data.Width, data.Height, dpiX, dpiY,
                                            GetPixelFormat(bitmap.PixelFormat), palette, data.Scan0 + data.Stride * data.Height, Math.Abs(data.Stride) * data.Height, Math.Abs(data.Stride));
        }
        else
        {
            cropppedImage = BitmapSource.Create(data.Width, data.Height, dpiX, dpiY,
                                                GetPixelFormat(bitmap.PixelFormat), palette, data.Scan0, Math.Abs(data.Stride) * data.Height, Math.Abs(data.Stride));
        }

其中 rect 完全在圖像邊界內。 根據 C# 文檔,正 Stride 表示自上而下的圖像,而負表示自下而上的圖像。 BitmapData 的Stride成員如何以及為什么在圖像的不同部分具有不同的符號?

據我了解(根據thisthis )一個圖像可以是自上而下或自下而上的,但只有其中一個。 就我而言,我同時有一個自上而下自下而上的圖像。

但這怎么會發生呢?

就 API 的規范而言,當然有可能(允許)每次調用LockBits時,您獲得的 memory 孔徑可能會以不同的方式呈現。 在鎖定它們之前,您無法訪問這些位,因此在鎖定它們之后如何向您呈現這些位完全取決於實現。 API 允許簽名的Stride ,因此實現可以在它想要的程度上利用它。 當您解鎖這些位然后再次鎖定它們時,API 可以在不同的地址以不同的步幅將這些位呈現給您。

因此,您可能應該為相同 bitmap 的LockBits的不同調用之間的步幅不同的可能性做好准備 (以支持正向和負向跨步的方式編寫您的代碼。)老實說,我看不出假設 memory 在隨后的LockBits調用中以相同的跨步標志排列的優勢。

至於這是否真的發生在具有特定實現的領域中,對我來說不是一個有趣的問題。 即使它現在沒有發生,它也可能在明天到來的更新中發生,因為就像我說的那樣,這取決於實施。 但是話雖如此,通常一旦確定了原始 bitmap memory 布局,出於效率原因,它可能會保持不變。 更改行順序至少會涉及將位復制到 memory 的不同區域,因此如果可能的話,不理會它會更有效。

這是一個案例,您可以在同一個 bitmap 上觀察到不同的步幅。 假設您有一個 bitmap 以自下而上的格式存儲在磁盤上。 在從磁盤讀取但被鎖定為非本地格式后,該實現在將其轉碼為不同的(例如更寬的)像素格式后將其翻轉。 PixelFormat.Format16bppRgb555中鎖定像素本機可能會讓您自下而上,但隨后將它們鎖定在PixelFormat.Format32bppRgb可能會翻轉行順序並呈現具有正跨度的緩沖區,因為這就是內部轉碼器可能工作的方式:始終分配自上而下即使源格式是自下而上的,也是新格式的目標。

將此源代碼視為在實踐中可能發生這種情況的證據,即使源格式具有負跨度,它也始終為鎖定在非本地格式中的位圖選擇正跨度。

作為另一個示例,當鎖定的矩形不滿足某些標准(例如,4 字節寬度的倍數)時,實現可以選擇執行復制/轉碼,從而導致為復制的位分配的緩沖區的步長,這可能不同於原本的。

暫無
暫無

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

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