Hình ảnh của tôi bị mờ! Tại sao SnapsToDevicePixels của WPF không hoạt động?


165

Tôi đang sử dụng một số hình ảnh trong ứng dụng WPF của mình.

XAML:

<Image Name="ImageOrderedList"
       Source="images/OrderedList.png"
       ToolTip="Ordered List"
       Margin="0,0,5,5"
       Width="20"
       Height="20"
       SnapsToDevicePixels="True"
       MouseUp="Image_MouseUp"
       MouseEnter="Image_MouseEnter"
       MouseLeave="Image_MouseLeave" />

Nhưng, chúng xuất hiện mờ nhạt.

Tại sao SnapsToDevicePixels="True"dòng đó không ngăn chặn vấn đề này?



4
Liên kết hình ảnh của bạn dường như đã bị phá vỡ. Nếu bạn vẫn còn hình ảnh gốc, vui lòng tải lại chúng vào stack.imgur. Cảm ơn.
Ilmari Karonen

1
Nếu không có mẹo nào dưới đây hoạt động ngay lập tức, hãy thử và thay đổi kích thước hình ảnh của bạn thành hệ số 4 chiều rộng và chiều cao. Vì vậy, thay vì 179 X 44, hãy thử 176 X 44.
Martin Xổ số

Câu trả lời:


233

Bạn có thể muốn xem xét thử một tài sản mới hiện có trong WPF4 . Rời khỏi RenderOptions.BitmapScalingModeđể có chất lượng cao hoặc chỉ không khai báo nó.

Người hàng xóm gần nhất làm việc cho tôi ngoại trừ nó dẫn đến bitmap khi phóng to ứng dụng. Nó dường như cũng không khắc phục được bất kỳ trục trặc nào trong đó các biểu tượng được định cỡ theo những cách kỳ lạ.

Trên phần tử gốc của bạn (tức là cửa sổ chính của bạn) thêm thuộc tính này : UseLayoutRounding="True".

Một thuộc tính trước đây chỉ có trong Silverlight hiện đã sửa tất cả các tai ương kích thước Bitmap. :)


4
Thông tin thêm về bất động sản mới đây tìm thấy ở đây: blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx
Domokun

5
UseLayoutRendering = "True" là những gì tôi đã sử dụng - điều này là hoàn hảo để giải quyết các hình ảnh mờ của tôi. Cảm ơn!
Matt DeKrey

25
CUỐI CÙNG !! UseLayoutRounding nên được đặt theo mặc định. Hình ảnh hiển thị giống như văn bản gốc và thậm chí ở một số nơi (như ContextMenus, đối với tôi ít nhất) hiển thị sắc nét hơn trước. Cảm ơn, Domokun!
cấp

3
Tôi đoán những người trong chúng ta vẫn bị mắc kẹt trên .NET 3.5 không có tùy chọn?
jpierson

2
Tôi thấy rằng điều này sẽ khắc phục vấn đề của tôi nếu tôi đặt thuộc tính Stretch thành Không có trên hình ảnh, nhưng trong tất cả các tình huống khác, ngay cả khi kết xuất và khử răng cưa HighQuality bị tắt, việc kéo dài hình ảnh vẫn bị mất trong WPF. Nhưng, ít nhất điều này đã khắc phục sự cố cho hình ảnh không bị kéo dài (điều không nên xảy ra ở nơi đầu tiên)
Christian Findlay

74

Thay vì sử dụng SnapsToDevicePixels, thay vào đó tôi đã sử dụng RenderOptions.BitmapScalingModevà giờ đây chúng rất đẹp và sắc nét!

XAML:

<Image Name="ImageOrderedList"
       Source="images/OrderedList.png"
       ToolTip="Ordered List"
       Margin="0,0,5,5"
       Width="20"
       Height="20"
       RenderOptions.BitmapScalingMode="NearestNeighbor"
       MouseUp="Image_MouseUp"
       MouseEnter="Image_MouseEnter"
       MouseLeave="Image_MouseLeave" />

1
Ngoài ra, nếu hình ảnh của bạn có kích thước chính xác như được chỉ định trong thẻ <Image>, thì nó sẽ không phải chia tỷ lệ và sẽ hiển thị hình ảnh rõ nét.
Beardo

1
Tôi không chắc điều này sẽ có hiệu ứng mong muốn ở DPI khác
Dave

1
Beardo, cả đồ họa nguồn và <Image> đều có 20 pixel x 20 pixel. Theo tôi hiểu, vấn đề xuất phát từ WPF. Nó muốn loại bỏ lưới pixel của màn hình, do đó, lưới logic thường không phù hợp hoàn hảo với lưới vật lý.
Zack Peterson

9
@Zack Width = "20" không có nghĩa là 20 pixel. Nó có nghĩa là 20/96 của một inch. Nếu HĐH của bạn được cấu hình để chạy ở 96 DPI thì đó là 20 pixel. Bây giờ làm thế nào hàng xóm gần nhất của bạn sẽ nhìn vào một màn hình tốt, chẳng hạn 160 DPI? Và nó sẽ trông như thế nào khi bạn in ở 300 DPI? Bạn không nên tối ưu hóa cho máy dev của bạn.
Frank Krueger

2
Tôi cũng thấy rằng đối với các hình ảnh có kích thước pixel thì RecentNeighbor tốt hơn nhiều so với HighQuality, đặc biệt nếu bạn kết hợp nó với img.Width = imgSource.PixelWidth; img.Height = imgSource.PixelHeight. Khách hàng của tôi đã cung cấp một số hình ảnh với các giá trị DPI điên rồ khác nhau và tôi không thể yêu cầu khách hàng chuyển đổi tất cả, vì vậy tôi phải sử dụng bản hack này.
JustAMartin

23

+1 cho Zack Peterson

Tôi đang sử dụng .Net 3.5 sp1 và có vẻ như là giải pháp đơn giản nhất cho một số lượng lớn hình ảnh mờ. Việc xác định RenderOptions tại chỗ không phải là vấn đề lớn, nhưng đối với các thành phần bên thứ 3, một phong cách trong tài nguyên cấp ứng dụng có ý nghĩa:

 <Style TargetType="{x:Type Image}">
    <Setter
        Property="RenderOptions.BitmapScalingMode"
        Value="NearestNeighbor" />
 </Style>

Hoạt động độc đáo khi AvalonDock bắt đầu hiển thị các biểu tượng mờ.


1
AvalonDock cũng khiến tôi đau đầu tương tự ... và tôi vẫn ở với .Net 3.5
Ignacio Soler Garcia

9

Sử dụng UseLayoutRounding="True"trên cửa sổ gốc hoạt động trong nhiều trường hợp nhưng tôi gặp phải sự cố khi sử dụng điều khiển WPF Ribbon . Ứng dụng của tôi dựa trên Tabs theo ngữ cảnh mà xuất hiện theo những gì người dùng đang làm và khi tôi đặt UseLayoutRoundingđểTrue , tab theo ngữ cảnh sẽ không hiển thị và hình ảnh của RibbonButton không. Ngoài ra, ứng dụng đóng băng trong nhiều giây và quạt CPU bắt đầu hát.

Sử dụng RenderOptions.BitmapScalingMode="NearestNeighbor"trên hình ảnh của tôi đã khắc phục các sự cố hiển thị hình ảnh (hình ảnh mờ và bị cắt) và hoàn toàn tương thích với việc sử dụng Tab theo ngữ cảnh Ribbon.


1
UseLayoutRounding = "True" hoạt động với tôi. Cảm ơn. mikecroteau.wordpress.com/2013/01/20/wpf-net-xaml-blurry-images
mcroteau

6

RenderOptions.BitmapScalingMode = "RecentNeighbor" hoạt động tốt hầu hết thời gian. Tuy nhiên, đôi khi bạn sẽ gặp trục trặc về đồ họa (trong trường hợp của tôi, 4 trong số 5 hình ảnh hiển thị tốt, nhưng thứ năm có một chút biến dạng ở cạnh phải). Tôi đã sửa lỗi tăng lề phải của điều khiển hình ảnh lên 1.

Nếu điều đó vẫn không khắc phục được, hãy thử điều khiển lớp Bitmap ở trên mà EugeneZ đề cập. Đó là một sự thay thế cho điều khiển hình ảnh và cho đến nay nó hoạt động khá tốt đối với tôi. Xem http://bloss.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx


5

Đảm bảo bạn lưu hình ảnh trong cùng DPI khi ứng dụng WPF của bạn đang hoạt động, một số định dạng hình ảnh có thông tin này được lưu trữ dưới dạng siêu dữ liệu. Tôi không biết liệu điều này có giải quyết được vấn đề không nhưng tôi đã giải quyết được một số vấn đề vì điều này khi hình ảnh được thay đổi kích thước thành 100% lớn hơn hoặc nhỏ hơn dự kiến.

Có thể là một cái gì đó tương tự.


5

sử dụng UseLayoutRounding = Đúng với phần tử hàng đầu trong ứng dụng của bạn



3

Tôi đã thấy rằng RenderOptions.BitmapScalingMode = "RecentNeighbor" không hoạt động với tôi. Tôi đang sử dụng Windows XP x32 với DirectX 9.0c. Vì kết xuất thực tế cho WPF được thực hiện với DirectX, điều này có thể có hiệu lực. Tôi đã bật khử răng cưa cho XP với các mục đăng ký sau:

[HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Avalon.Graphics] "MaxMultisampleType" = dword: 00000004 "EnableDebugControl" = dword: 00000001

Tuy nhiên, tắt aa bằng các cài đặt này không ảnh hưởng đến hình ảnh. Tôi nghĩ rằng điều này chỉ ảnh hưởng đến Chế độ xem 3D.

Cuối cùng, tôi thấy rằng việc làm mờ xảy ra với văn bản của TextBlocks cũng như hình ảnh. Và việc làm mờ chỉ xảy ra đối với một số khối văn bản và hình ảnh, không phải tất cả chúng.


3

Tôi đã tìm thấy rằng không có sự kết hợp của các cách giải quyết được đề xuất sẽ chữa được vấn đề hình ảnh mờ dường như ngẫu nhiên của tôi. Tôi thích nhiều người khác không thể nâng cấp lên .net 4 để sử dụng UseLayoutRenderingtài sản.

Những gì tôi đã tìm thấy để làm việc:

  • Đảm bảo kích thước hình ảnh [gốc] của bạn là bội số của 2. Điều này dường như ngăn chặn một số vấn đề về tỷ lệ hình ảnh thú vị.
  • Đôi khi tôi cũng thấy rằng việc điều chỉnh lề trên ảnh bằng pixel hoặc 2 có thể ngăn chặn sự cố.

1

Suy nghĩ đầu tiên của tôi, khi đọc câu hỏi, là bạn đã thổi tung hình ảnh quá nhiều, nhưng dường như đó không phải là trường hợp nhìn vào hình ảnh bạn có của ứng dụng.

Suy nghĩ thứ hai là bảng màu, nhưng với màu đen là một trong những màu không được hiển thị chính xác, điều này không có khả năng.

Nếu bạn có thể loại trừ hoàn toàn hai điều trên, tôi hiện đang bị bối rối.

Là một thử nghiệm, bạn có thể thử các định dạng đồ họa khác, nhưng PNG sẽ ổn. Tôi sẽ phải suy nghĩ thêm thông qua một số câu trả lời tốt hơn.


1
+1 để tránh bỏ phiếu tiêu cực không chính đáng vì tôi nghĩ rằng bạn đã đưa ra một số đề xuất hợp lý và chỉ cố gắng giúp đỡ và quan trọng nhất là không có gì sai với đề xuất của bạn.
jpierson

1

Tôi đã thử sử dụng RenderOptions.BitmapScalingMode = HighQuality, có vẻ như gây ra một số vấn đề trong Windows 8.1, vì vậy những gì tôi đã làm là chạy chúng thông qua công cụ có tên PngOut.exe

http://advsys.net/ken/utils.htm

Điều này làm giảm tiêu đề của png, và cũng làm giảm kích thước, nhưng không thay đổi chất lượng hình ảnh.

Và bây giờ tất cả hình ảnh của tôi là hoàn hảo! :-)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.