ภาพของฉันพร่ามัว! ทำไม SnapsToDevicePixels ของ WPF ไม่ทำงาน


165

ฉันใช้อิมเมจบางอย่างใน applcation WPF ของฉัน

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" />

แต่พวกเขาดูเลือนลาง

เหตุใดSnapsToDevicePixels="True"บรรทัดนั้นจึงไม่ป้องกันปัญหานี้



4
ลิงค์รูปภาพของคุณดูเหมือนจะเสีย หากคุณยังคงมีภาพต้นฉบับโปรดอัปโหลดใหม่เป็น stack.imgur ขอบคุณ
Ilmari Karonen

1
หากเคล็ดลับด้านล่างไม่ทำงานให้ลองเปลี่ยนขนาดของภาพเป็นสัดส่วน 4 ในความกว้างและความสูง ดังนั้นแทนที่จะเป็น 179 X 44 ให้ลอง 176 X 44
Martin Lottering

คำตอบ:


233

คุณอาจต้องการที่จะต้องพิจารณาพยายามคุณสมบัติใหม่ที่มีอยู่ในขณะนี้ในWPF4 ออกจากRenderOptions.BitmapScalingModeการมีคุณภาพสูงหรือเพียงแค่ไม่ประกาศ

เพื่อนบ้านที่ใกล้ที่สุดทำงานให้ฉันยกเว้นจะนำไปสู่บิตแมปแบบ jaggy เมื่อซูมเข้าแอปพลิเคชัน มันก็ดูเหมือนจะไม่ได้แก้ไขข้อบกพร่องใด ๆ ที่ไอคอนมีการปรับขนาดในรูปแบบแปลก ๆ

ในองค์ประกอบรากของคุณ (เช่นหน้าต่างหลักของคุณ) UseLayoutRounding="True"เพิ่มคุณสมบัตินี้:

ก่อนหน้านี้สถานที่ให้บริการเฉพาะใน Silverlight ตอนนี้ได้แก้ไขการปรับขนาดบิตแมปทั้งหมด :)


4
ข้อมูลเพิ่มเติมเกี่ยวกับอสังหาริมทรัพย์ใหม่นี้พบได้ที่นี่: blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx
Domokun

5
UseLayoutRendering = "True" เป็นสิ่งที่ฉันใช้ - มันเหมาะสำหรับการแก้ไขภาพพร่ามัวของฉัน ขอบคุณ!
Matt DeKrey

25
ในที่สุด !! UseLayoutRounding ควรตั้งค่าเริ่มต้น รูปภาพปรากฏขึ้นเหมือนต้นฉบับและแม้กระทั่งข้อความในบางสถานที่ (เช่น ContextMenus สำหรับฉันอย่างน้อย) แสดงภาพที่คมชัดกว่า แต่ก่อน ขอบคุณ Domokun!
อนุญาต

3
ฉันเดาพวกเรายังติดอยู่บน. NET 3.5 ไม่มีตัวเลือก?
jpierson

2
ฉันพบว่าสิ่งนี้ช่วยแก้ไขปัญหาของฉันได้ถ้าฉันตั้งค่าคุณสมบัติขยายเป็นไม่มีบนรูปภาพ แต่ในสถานการณ์อื่น ๆ ทั้งหมดแม้จะปิดการแสดงภาพ HighQuality และการใช้นามแฝงแล้วการยืดภาพยังคงแย่อยู่ใน WPF แต่อย่างน้อยสิ่งนี้ได้แก้ไขปัญหาของภาพที่ไม่ยืด (ซึ่งไม่น่าจะมีปัญหาตั้งแต่แรก)
Christian Findlay

74

แทนที่จะใช้SnapsToDevicePixelsฉันใช้แทนRenderOptions.BitmapScalingModeและตอนนี้พวกเขาดีและคมชัด!

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
นอกจากนี้หากภาพของคุณมีขนาดที่แน่นอนตามที่ระบุไว้ในแท็ก <Image> มันก็ไม่จำเป็นต้องปรับขนาดและควรจะทำให้มันคมชัด
Beardo

1
ฉันไม่แน่ใจว่าสิ่งนี้จะมีผลตามที่ต้องการใน DPI อื่น
เดฟ

1
Beardo ทั้งซอร์สกราฟิกและ <Image> มีทั้ง 20 พิกเซลคูณ 20 พิกเซล ตามที่ฉันเข้าใจแล้วปัญหามาจาก WPF มันต้องการเรียงลำดับพิกเซลกริดของจอภาพดังนั้นโดยปกติแล้วกริดโลจิคัลจะไม่สอดคล้องกับกริดฟิสิคัลอย่างสมบูรณ์แบบ
Zack Peterson

9
@Zack Width = "20" ไม่ได้หมายถึง 20 พิกเซล มันหมายถึง 20/96 นิ้ว หากระบบปฏิบัติการของคุณได้รับการกำหนดค่าให้ทำงานที่ 96 DPI แสดงว่าเป็น 20 พิกเซล ทีนี้เพื่อนบ้านที่ใกล้ที่สุดของคุณจะมองดูจอภาพที่ดีอย่างเช่น 160 DPI อย่างไร และจะมีลักษณะอย่างไรเมื่อคุณพิมพ์ที่ 300 DPI คุณไม่ควรปรับให้เหมาะสมสำหรับเครื่อง dev ของคุณ
Frank Krueger

2
ฉันยังพบว่าสำหรับภาพที่มีขนาดพิกเซลใกล้เคียงที่สุดคือเพื่อนบ้านที่ดีกว่า HighQuality โดยเฉพาะอย่างยิ่งถ้าคุณรวมเข้ากับ img.Width = imgSource.PixelWidth; img.Height = imgSource.PixelHeight ลูกค้าของฉันให้ภาพที่มีค่า DPI ที่แตกต่างกันและฉันไม่สามารถขอให้ลูกค้าแปลงพวกเขาทั้งหมดได้ดังนั้นฉันจึงต้องใช้แฮ็คนี้
JustAMartin

23

+1 สำหรับ Zack Peterson

ฉันใช้. Net 3.5 sp1 และดูเหมือนโซลูชันที่ง่ายที่สุดสำหรับรูปภาพฟัซซี่จำนวนมาก ไม่ใช่เรื่องใหญ่ที่จะระบุ RenderOptions ในสถานที่ แต่สำหรับองค์ประกอบของบุคคลที่สามสไตล์ในทรัพยากรระดับแอปมีเหตุผล:

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

ทำงานได้ดีเมื่อ AvalonDock เริ่มแสดงผลไอคอนเบลอ


1
AvalonDock ยังทำให้ฉันปวดหัวเหมือนเดิม ... และฉันยังอยู่กับ. Net 3.5
Ignacio Soler Garcia

9

การใช้UseLayoutRounding="True"บนหน้าต่างรากทำงานได้ในหลายกรณี แต่ฉันพบปัญหาเมื่อใช้ตัวควบคุมWPF Ribbon แอปพลิเคชันของฉันขึ้นอยู่กับแท็บบริบทที่ปรากฏตามสิ่งที่ผู้ใช้ทำและเมื่อฉันตั้งค่าUseLayoutRoundingให้Trueแท็บบริบทจะไม่ปรากฏขึ้นและภาพของ RibbonButton นอกจากนี้แอปพลิเคชันค้างเป็นเวลาหลายวินาทีและแฟน CPU เริ่มร้องเพลง

การใช้RenderOptions.BitmapScalingMode="NearestNeighbor"ภาพของฉันแก้ไขปัญหาการเรนเดอร์รูปภาพ (ภาพเลือนและเกรียน) และเข้ากันได้อย่างสมบูรณ์กับการใช้แท็บ Ribbon ตามบริบท


1
UseLayoutRounding = "True" ใช้ได้สำหรับฉัน ขอบคุณ mikecroteau.wordpress.com/2013/01/20/wpf-net-xaml-blurry-images
mcroteau

6

RenderOptions.BitmapScalingMode = "ใกล้เคียงที่สุด" ทำงานได้ดีเกือบตลอดเวลา อย่างไรก็ตามในบางครั้งคุณจะได้รับความผิดพลาดแบบกราฟิก (ในกรณีของฉันภาพจาก 4 ใน 5 ภาพปรากฏได้ดี แต่ภาพที่ห้ามีการบิดเบือนเล็กน้อยที่ขอบขวา) ฉันแก้ไขการเพิ่มระยะขอบด้านขวาของ Image control โดย 1

หากยังไม่สามารถแก้ไขได้ลองใช้ตัวควบคุมคลาส Bitmap ด้านบนที่ EugeneZ กล่าวถึง มันใช้แทนตัวควบคุมรูปภาพและจนถึงตอนนี้มันใช้งานได้ดีสำหรับฉัน ดูhttp://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx


5

ตรวจสอบให้แน่ใจว่าคุณบันทึกภาพใน DPI เดียวกันกับที่แอปพลิเคชัน WPF ของคุณทำงานอยู่รูปแบบภาพบางรูปแบบมีข้อมูลนี้จัดเก็บเป็นข้อมูลเมตา ฉันไม่ทราบว่าจะแก้ปัญหาได้หรือไม่ แต่ฉันได้ซ่อนปัญหาบางอย่างไว้เนื่องจากสิ่งนี้ซึ่งภาพที่ปรับขนาดเป็น 100% ใหญ่กว่าหรือเล็กกว่าที่คาดไว้

อาจเป็นสิ่งที่คล้ายกัน


5

use UseLayoutRounding = Trueเพื่อองค์ประกอบอันดับต้น ๆ ในแอปพลิเคชันของคุณ



3

ฉันพบว่า RenderOptions.BitmapScalingMode = "ใกล้เคียงที่สุดเพื่อนบ้าน" ไม่ทำงานสำหรับฉัน ฉันใช้ Windows XP x32 กับ DirectX 9.0c เนื่องจากการเรนเดอร์ที่แท้จริงสำหรับ WPF ทำได้ด้วย DirectX นี่อาจมีผลกระทบ ฉันเปิดใช้ anti-aliasing สำหรับ XP ด้วยรายการรีจิสตรีต่อไปนี้:

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

อย่างไรก็ตามการปิดการตั้งค่าเหล่านี้ไม่มีผลกับภาพ ฉันคิดว่าสิ่งนี้มีผลเฉพาะการดู 3D เท่านั้น

ในที่สุดฉันก็พบว่าการเบลอที่เกิดขึ้นกับข้อความของ TextBlocks รวมถึงรูปภาพ และการเบลอจะเกิดขึ้นเฉพาะกับบล็อคข้อความและรูปภาพบางอย่างเท่านั้นไม่ใช่ทั้งหมด


3

ฉันพบว่าไม่มีวิธีแก้ไขปัญหาที่แนะนำร่วมกันจะช่วยแก้ไขปัญหาภาพเบลอที่สุ่มของฉันได้ ฉันชอบคนอื่น ๆ ไม่สามารถอัพเกรดเป็น. net 4 เพื่อใช้UseLayoutRenderingคุณสมบัตินี้ได้

สิ่งที่ฉันได้พบในการทำงาน:

  • ตรวจสอบให้แน่ใจว่าขนาดภาพต้นฉบับของคุณนั้นทวีคูณเป็น 2 ซึ่งจะช่วยป้องกันปัญหาการปรับขนาดภาพที่ขี้ขลาด
  • บางครั้งฉันก็พบว่าการปรับระยะขอบของภาพด้วยพิกเซลหรือ 2 สามารถป้องกันปัญหาได้

1

ความคิดแรกของฉันในการอ่านคำถามคือคุณกำลังทำให้ภาพแตกต่างไปมากเกินไป แต่นั่นไม่ได้เป็นกรณีที่มองภาพที่คุณมีในแอพ

ความคิดที่สองคือจานสี แต่ด้วยสีดำเป็นหนึ่งในสีที่แสดงผลไม่ถูกต้องจึงไม่น่าจะเป็นไปได้

หากคุณสามารถแยกแยะทั้งสองอย่างได้อย่างสมบูรณ์ฉันก็นิ่งงันอยู่ในขณะนี้

ในการทดสอบคุณสามารถลองรูปแบบกราฟิกอื่น ๆ ได้ แต่ PNG น่าจะใช้ได้ ฉันจะต้องคิดให้รอบคอบเพื่อหาคำตอบที่ดีกว่า


1
+1 เพื่อปัดคะแนนโหวตติดลบเนื่องจากฉันคิดว่าคุณเสนอคำแนะนำที่สมเหตุสมผลและพยายามช่วยเท่านั้นและที่สำคัญที่สุดคือไม่มีข้อผิดพลาดใด ๆ กับคำแนะนำของคุณ
jpierson

1

ฉันพยายามใช้ RenderOptions.BitmapScalingMode = HighQuality ดูเหมือนว่าจะทำให้เกิดปัญหาบางอย่างใน Windows 8.1 ดังนั้นสิ่งที่ฉันทำคือการเรียกใช้พวกเขาผ่านเครื่องมือที่เรียกว่า PngOut.exe

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

ซึ่งช่วยลดส่วนหัวของ png และยังลดขนาด แต่ไม่เปลี่ยนคุณภาพของภาพ

และตอนนี้ภาพทั้งหมดของฉันสมบูรณ์แบบ! :-)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.