簡體   English   中英

DrawImage 無法 position 正確切片圖像

[英]DrawImage fails to position sliced images correctly

幾天來,我試圖弄清楚為什么我的九片代碼不能按預期工作。 據我所見,Graphics.DrawImage 方法似乎存在問題,它錯誤地處理了我的九個切片圖像。 所以我的問題是如何補償在緊湊框架上運行我的代碼時執行的不正確縮放。 我可能會補充一點,當在完整的框架環境中運行時,這段代碼當然可以完美運行。 僅當將圖像縮放到更大的圖像時才會出現此問題,而不是相反。 這是片段:

public class NineSliceBitmapSnippet
{
    private Bitmap m_OriginalBitmap;

    public int CornerLength { get; set; }

    /// <summary>
    /// Initializes a new instance of the NineSliceBitmapSnippet class.
    /// </summary>
    public NineSliceBitmapSnippet(Bitmap bitmap)
    {
        CornerLength = 5;
        m_OriginalBitmap = bitmap;
    }

    public Bitmap ScaleSingleBitmap(Size size)
    {
        Bitmap scaledBitmap = new Bitmap(size.Width, size.Height);
        int[] horizontalTargetSlices = Slice(size.Width);
        int[] verticalTargetSlices = Slice(size.Height);

        int[] horizontalSourceSlices = Slice(m_OriginalBitmap.Width);
        int[] verticalSourceSlices = Slice(m_OriginalBitmap.Height);

        using (Graphics graphics = Graphics.FromImage(scaledBitmap))
        {
            using (Brush brush = new SolidBrush(Color.Fuchsia))
            {
                graphics.FillRectangle(brush, new Rectangle(0, 0, size.Width, size.Height));
            }

            int horizontalTargetOffset = 0;
            int verticalTargetOffset = 0;

            int horizontalSourceOffset = 0;
            int verticalSourceOffset = 0;

            for (int x = 0; x < horizontalTargetSlices.Length; x++)
            {
                verticalTargetOffset = 0;
                verticalSourceOffset = 0;
                for (int y = 0; y < verticalTargetSlices.Length; y++)
                {
                    Rectangle destination = new Rectangle(horizontalTargetOffset, verticalTargetOffset, horizontalTargetSlices[x], verticalTargetSlices[y]);
                    Rectangle source = new Rectangle(horizontalSourceOffset, verticalSourceOffset, horizontalSourceSlices[x], verticalSourceSlices[y]);

                    graphics.DrawImage(m_OriginalBitmap, destination, source, GraphicsUnit.Pixel);

                    verticalTargetOffset += verticalTargetSlices[y];
                    verticalSourceOffset += verticalSourceSlices[y];
                }

                horizontalTargetOffset += horizontalTargetSlices[x];
                horizontalSourceOffset += horizontalSourceSlices[x];
            }
        }
        return scaledBitmap;
    }

    public int[] Slice(int length)
    {
        int cornerLength = CornerLength;

        if (length <= (cornerLength * 2))
            throw new Exception("Image to small for sliceing up");

        int[] slices = new int[3];
        slices[0] = cornerLength;
        slices[1] = length - (2 * cornerLength);
        slices[2] = cornerLength;

        return slices;
    }
}

所以,我的問題是,現在有人可以如何補償不正確的縮放比例嗎?

/擔

經過更多的反復試驗,我終於找到了解決問題的方法。 縮放問題一直是頂部中心、右側中心、底部中心和左側中心切片,因為根據九個切片縮放的邏輯,它們總是僅在一個方向上拉伸。 如果我在應用正確的拉伸之前對這些切片應用臨時方形拉伸,則最終的 bitmap 將是正確的。 再一次,該問題僅在 Windows CE 設備(智能設備)的 .Net Compact Framework 中可見。 這是一個代碼片段,其中包含針對 CF 中的錯誤進行調整的代碼。 我現在唯一擔心的是,由於校正代碼的原因,被方形拉伸的切片將占用更多的 memory。 另一方面,這一步只是很短的時間,所以我可能會僥幸成功。 ;)

    public class NineSliceBitmapSnippet
{
    private Bitmap m_OriginalBitmap;

    public int CornerLength { get; set; }

    public NineSliceBitmapSnippet(Bitmap bitmap)
    {
        CornerLength = 5;
        m_OriginalBitmap = bitmap;
    }

    public Bitmap Scale(Size size)
    {
        if (m_OriginalBitmap != null)
        {
            return ScaleSingleBitmap(size);
        }

        return null;
    }

    public Bitmap ScaleSingleBitmap(Size size)
    {
        Bitmap scaledBitmap = new Bitmap(size.Width, size.Height);
        int[] horizontalTargetSlices = Slice(size.Width);
        int[] verticalTargetSlices = Slice(size.Height);

        int[] horizontalSourceSlices = Slice(m_OriginalBitmap.Width);
        int[] verticalSourceSlices = Slice(m_OriginalBitmap.Height);

        using (Graphics graphics = Graphics.FromImage(scaledBitmap))
        {
            using (Brush brush = new SolidBrush(Color.Fuchsia))
            {
                graphics.FillRectangle(brush, new Rectangle(0, 0, size.Width, size.Height));
            }

            int horizontalTargetOffset = 0;
            int verticalTargetOffset = 0;

            int horizontalSourceOffset = 0;
            int verticalSourceOffset = 0;

            for (int x = 0; x < horizontalTargetSlices.Length; x++)
            {
                verticalTargetOffset = 0;
                verticalSourceOffset = 0;
                for (int y = 0; y < verticalTargetSlices.Length; y++)
                {
                    Rectangle destination = new Rectangle(horizontalTargetOffset, verticalTargetOffset, horizontalTargetSlices[x], verticalTargetSlices[y]);
                    Rectangle source = new Rectangle(horizontalSourceOffset, verticalSourceOffset, horizontalSourceSlices[x], verticalSourceSlices[y]);

                    bool isWidthAffectedByVerticalStretch = (y == 1 && (x == 0 || x == 2) && destination.Height > source.Height);
                    bool isHeightAffectedByHorizontalStretch = (x == 1 && (y == 0 || y == 2) && destination.Width > source.Width);
                    if (isHeightAffectedByHorizontalStretch)
                    {
                        BypassDrawImageError(graphics, destination, source, Orientation.Horizontal);
                    }
                    else if (isWidthAffectedByVerticalStretch)
                    {
                        BypassDrawImageError(graphics, destination, source, Orientation.Vertical);
                    }
                    else
                    {
                        graphics.DrawImage(m_OriginalBitmap, destination, source, GraphicsUnit.Pixel);
                    }

                    verticalTargetOffset += verticalTargetSlices[y];
                    verticalSourceOffset += verticalSourceSlices[y];
                }

                horizontalTargetOffset += horizontalTargetSlices[x];
                horizontalSourceOffset += horizontalSourceSlices[x];
            }
        }
        return scaledBitmap;
    }

    private void BypassDrawImageError(Graphics graphics, Rectangle destination, Rectangle source, Orientation orientationAdjustment)
    {
        Size adjustedSize = Size.Empty;
        switch (orientationAdjustment)
        {
            case Orientation.Horizontal:
                adjustedSize = new Size(destination.Width, destination.Width);
                break;
            case Orientation.Vertical:
                adjustedSize = new Size(destination.Height, destination.Height);
                break;
            default:
                break;
        }

        using (Bitmap quadScaledBitmap = new Bitmap(adjustedSize.Width, adjustedSize.Height))
        {
            using (Graphics tempGraphics = Graphics.FromImage(quadScaledBitmap))
            {
                tempGraphics.Clear(Color.Fuchsia);
                tempGraphics.DrawImage(m_OriginalBitmap, new Rectangle(0, 0, adjustedSize.Width, adjustedSize.Height), source, GraphicsUnit.Pixel);
            }
            graphics.DrawImage(quadScaledBitmap, destination, new Rectangle(0, 0, quadScaledBitmap.Width, quadScaledBitmap.Height), GraphicsUnit.Pixel);
        }
    }

    public int[] Slice(int length)
    {
        int cornerLength = CornerLength;

        if (length <= (cornerLength * 2))
            throw new Exception("Image to small for sliceing up");

        int[] slices = new int[3];
        slices[0] = cornerLength;
        slices[1] = length - (2 * cornerLength);
        slices[2] = cornerLength;

        return slices;
    }
}

暫無
暫無

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

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