簡體   English   中英

WinRT:如何確保在畫布上以像素完美的方式繪制圖像?

[英]WinRT: How do I ensure Images are drawn in a pixel-perfect way on a Canvas?

我在Windows運行時環境中將圖像實例添加到Canvas中,並且在140和180的縮放分辨率顯示中,圖像不斷放大,縮放分辨率為100時看起來很完美。我嘗試創建3個PNG圖像,每個縮放尺寸一個:100 ,140、180,但仍會按比例放大它們,並且看起來模糊。 我在青色背景上創建了一個具有4個黑色像素的測試圖像,並從模擬器中截取了屏幕截圖,看看圖像是如何模糊的,我的原始圖像只有4個完美的黑色像素:

模糊,相信我

我嘗試更改Image對象的拉伸模式,但無濟於事。 我正在使用以下代碼在運行時添加圖像:

var bitmapImage = new BitmapImage();
StorageFile bitmapFile = await StorageFile.GetFileFromApplicationUriAsync(imageUri);
await bitmapImage.SetSourceAsync(await bitmapFile.OpenReadAsync());

Image image = new Image{ Source = bitmapImage};
image.SetValue(Canvas.LeftProperty, x);
image.SetValue(Canvas.TopProperty, y);
canvas.Children.Add(image);

如何獲得圖像以在畫布中完美繪制像素,而無需縮放並以所需的確切x / y坐標?

我認為我有一種解決方法,但是它需要兩個步驟:

首先,我必須使用一種更標准的方式來加載圖像,而不涉及像這樣獲取文件路徑。

var bitmapImage = new BitmapImage(imageUri);

某種程度上,這必須在內部保留更多信息,即該圖像來自具有當前顯示的相應ResolutionScale的文件。 因此,當它由畫布繪制時,它根本不會縮放。 但是,這只能解決一半的問題。

下一個問題是用於指定在何處繪制圖像的x,y坐標已縮放,因此將圖像繪制在錯誤的位置,而不是我想要的位置。 我唯一能做的就是首先對它們進行縮放,如下所示:

var resScale = DisplayInformation.GetForCurrentView().ResolutionScale;
Image image = new Image{ Source = bitmapImage};
image.SetValue(Canvas.LeftProperty, (x * 100.0) / (int)resScale);
image.SetValue(Canvas.TopProperty, (y * 100.0) / (int)resScale);
canvas.Children.Add(image);

整個過程似乎有些瘋狂,但到目前為止它似乎仍然有效……任何人都有更好的解決方案或解釋,為什么所有這些都是必要的? 似乎Canvas類需要一種不縮放的模式,該模式不會弄亂圖像或在不同分辨率的顯示器上進行坐標調整。

更新 :這不是完美的工作,使用雙精度值來存儲值會導致精度損失,有時還會出現抗鋸齒現象。 如果您想要像素完美的圖形,這是不可接受的。 我仍在尋找完美的解決方案。

還有其他一些事情可能會對您的解決方案有所幫助。

  1. 在圖像上使用UseLayoutRounding="False"
  2. 將“ Canvas放入全屏Viewbox ,然后將“ Canvas WidthHeight設置為屏幕分辨率。 在這種情況下,您將使用未縮放的Canvas.Left / Top值。
  3. 使用Direct2D / Direct3D進行渲染。

祝好運。

您可以將Stretch屬性更改為"None" ,如果圖像仍然網格化:

您應該查看保存在什么DPI上。 WPF試圖獨立於DPI,因此它試圖在每個大小相同的監視器上繪制5“ x5”的圖像。 即使分辨率更高,它仍應為5“ x5”,只有高分辨率才能以更高的質量渲染(光柵化)圖像。

這是一些信息: http : //www.wpflearningexperience.com/? p= 41

如何將WPF大小轉換為物理像素?

這是一段xaml代碼

您可以隨時使用從后面的代碼進行縮放變換,以將圖像縮放到適當的數量,無論其大小如何。

<Image  Canvas.Left="150"  Height="170" Width="170" Visibility="Visible" Stretch="None">
                <Image.Source >
                    <BitmapImage UriSource="ms-appx:///Assets/rollingDieSprite.png"></BitmapImage>
                </Image.Source>

                <Image.RenderTransform>
                    <ScaleTransform ScaleX="4" ScaleY="4" x:Name="scaleTfDie"></ScaleTransform>
                </Image.RenderTransform>
            </Image>

在后面的C#代碼中,您可以進行以下操作

ScaleTransform sc = new ScaleTransform();
            sc.ScaleX = 0.9;
            sc.ScaleY = 0.9;
            imgDieRolling.RenderTransform = sc;

這將控制縮放。 嘗試使用fill = none。 讓我知道它是否有效。

我發現這個問題也很成問題。 我正在創建自定義位圖,並將其繪制在畫布上的不同位置。 我在XAML中找不到方法,但是我發現了使用Direct2D的方法。 設置D2DContext時,有一個名為SetUnitMode()的函數。 默認的單位模式是“ DIPS”,這會導致所有圖形縮放。 通過切換到PIXELS模式,系統將停止按比例縮放圖形,並按1:1的比例完成所有操作。

m_d2dContext->SetUnitMode(D2D1_UNIT_MODE_PIXELS);

暫無
暫無

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

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