Gambar saya buram! Mengapa SnapsToDevicePixels WPF tidak berfungsi?

165

Saya menggunakan beberapa Gambar di aplikasi WPF saya.

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

Tapi, mereka tampak kabur.

Mengapa SnapsToDevicePixels="True"garis itu tidak mencegah masalah ini?

Zack Peterson
sumber
4
Tautan gambar Anda tampaknya rusak. Jika Anda masih memiliki gambar asli, harap unggah kembali gambar tersebut ke stack.imgur. Terima kasih.
Ilmari Karonen
1
Jika tidak ada tips di bawah ini yang langsung berfungsi, coba juga dan ubah ukuran gambar Anda menjadi faktor 4 lebar dan tinggi. Jadi alih-alih 179 X 44, coba 176 X 44.
Martin Lottering

Jawaban:

233

Anda mungkin ingin mempertimbangkan untuk mencoba properti baru yang tersedia sekarang di WPF4 . Serahkan RenderOptions.BitmapScalingModeke HighQuality atau jangan menyatakannya.

NearestNeighbor bekerja untuk saya kecuali itu menyebabkan bitmap jaggy ketika memperbesar aplikasi. Tampaknya juga tidak memperbaiki gangguan di mana ikon mengukur dengan cara yang aneh.

Pada elemen root Anda (yaitu jendela utama Anda) menambahkan properti ini: UseLayoutRounding="True".

Properti yang sebelumnya hanya tersedia di Silverlight sekarang telah memperbaiki semua masalah ukuran Bitmap. :)

Domokun
sumber
4
Informasi lebih lanjut mengenai properti baru ini ditemukan di sini: blogs.msdn.com/text/archive/2009/08/27/layout-rounding.aspx
Domokun
5
UseLayoutRendering = "True" adalah apa yang saya gunakan - ini sempurna untuk menyelesaikan gambar buram saya. Terima kasih!
Matt DeKrey
25
AKHIRNYA!! UseLayoutRounding harus diatur secara default. Gambar muncul seperti teks asli dan genap di beberapa tempat (seperti ContextMenus, setidaknya bagi saya) muncul lebih tajam dari sebelumnya. Terima kasih, Domokun!
berikan
3
Saya kira kita masih terjebak di. NET 3.5 tidak memiliki opsi?
jpierson
2
Saya menemukan bahwa ini memperbaiki masalah saya jika saya mengatur properti Stretch ke None pada gambar, tetapi dalam semua skenario lain, bahkan dengan rendering gambar HighQuality dan aliasing dimatikan, peregangan gambar masih menyebalkan di WPF. Tapi, setidaknya ini telah memperbaiki masalah untuk gambar yang tidak diregangkan (yang seharusnya tidak menjadi masalah)
Christian Findlay
74

Daripada menggunakan SnapsToDevicePixels, saya malah menggunakanRenderOptions.BitmapScalingMode dan sekarang bagus dan segar!

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" />
Zack Peterson
sumber
1
Juga jika gambar Anda adalah ukuran persis seperti yang ditentukan dalam tag <Image>, maka gambar itu tidak harus menskala dan membuatnya renyah.
Beardo
1
Saya tidak yakin ini akan memiliki efek yang diinginkan pada DPI yang berbeda
Dave
1
Beardo, baik grafik sumber maupun <Image> keduanya 20 piksel kali 20 piksel. Seperti yang saya pahami, masalah ini berasal dari WPF. Itu semacam ingin mengabaikan grid pixel monitor, jadi itu grid logis biasanya tidak akan sempurna sejalan dengan grid fisik.
Zack Peterson
9
@Zack Width = "20" tidak berarti 20 piksel. Ini berarti 20/96 inci. Jika OS Anda dikonfigurasi untuk berjalan pada 96 DPI maka itu adalah 20 piksel. Sekarang bagaimana tetangga terdekat Anda akan melihat monitor yang bagus, 160 DPI misalnya? Dan bagaimana tampilannya ketika Anda mencetak pada 300 DPI? Anda tidak harus mengoptimalkan untuk mesin dev Anda.
Frank Krueger
2
Saya juga menemukan bahwa untuk gambar berukuran piksel, NearestNeighbor jauh lebih baik daripada HighQuality, terutama jika Anda menggabungkannya dengan img.Width = imgSource.PixelWidth; img.Height = imgSource.PixelHeight. Klien saya memberikan beberapa gambar dengan nilai DPI gila yang berbeda dan saya tidak bisa meminta klien untuk mengonversi semuanya, jadi saya harus menggunakan retasan ini.
JustAMartin
23

+1 untuk Zack Peterson

Saya menggunakan. Net 3.5 sp1 dan sepertinya solusi paling sederhana untuk sejumlah besar gambar fuzzy. Bukan masalah besar untuk menentukan RenderOptions di tempat, tetapi untuk komponen pihak ketiga gaya dalam sumber daya tingkat aplikasi masuk akal:

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

Bekerja dengan baik ketika AvalonDock mulai membuat ikon buram.

DK.
sumber
1
AvalonDock juga memberi saya sakit kepala yang sama ... dan saya masih menggunakan .Net 3.5
Ignacio Soler Garcia
9

Menggunakan UseLayoutRounding="True" pada root Window berfungsi dalam banyak kasus tapi saya mengalami masalah ketika menggunakan kontrol WPF Ribbon . Aplikasi saya bergantung pada Kontekstual Tabs yang muncul sesuai dengan apa yang user lakukan dan ketika saya mengatur UseLayoutRoundinguntukTrue , tab kontekstual tidak akan muncul dan gambar RibbonButton ini tidak. Juga, aplikasi macet selama beberapa detik dan kipas CPU mulai bernyanyi.

Menggunakan RenderOptions.BitmapScalingMode="NearestNeighbor"pada gambar saya memperbaiki masalah rendering gambar (gambar kabur dan terpotong) dan sepenuhnya kompatibel dengan penggunaan Ribbon Contextual Tabs.

Omid B.
sumber
1
UseLayoutRounding = "True" bekerja untuk saya. Terima kasih. mikecroteau.wordpress.com/2013/01/20/wpf-net-xaml-blurry-images
mcroteau
6

RenderOptions.BitmapScalingMode = "NearestNeighbor" hampir selalu berfungsi dengan baik. Namun, kadang-kadang Anda akan mendapatkan gangguan grafis (dalam kasus saya, 4 dari 5 gambar muncul dengan baik, tetapi yang kelima memiliki sedikit distorsi di tepi kanan). Saya memperbaikinya saya meningkatkan margin kanan kontrol gambar dengan 1.

Jika itu masih belum memperbaikinya, coba kontrol kelas Bitmap di atas yang disebutkan EugeneZ. Ini adalah pengganti untuk kontrol Gambar dan sejauh ini bekerja dengan cukup baik untuk saya. Lihat http://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx


sumber
5

Pastikan Anda menyimpan gambar dalam DPI yang sama dengan aplikasi WPF Anda bekerja, beberapa format gambar menyimpan info ini sebagai metadata. Saya tidak tahu apakah ini menyelesaikan masalah, tetapi saya memiliki beberapa masalah karena ini di mana ukuran gambar hingga 100% menjadi lebih besar atau lebih kecil dari yang diharapkan.

Mungkin sesuatu yang serupa.


sumber
5

use UseLayoutRounding = Sesuai dengan elemen paling atas dalam aplikasi Anda

Varatharaj
sumber
3

Saya percaya ini adalah bug (atau setidaknya itu). Lihat halaman pertukaran email dukungan Microsoft ini untuk beberapa ide untuk memperbaikinya.

Bip bip
sumber
3

Saya telah menemukan bahwa RenderOptions.BitmapScalingMode = "NearestNeighbor" tidak berfungsi untuk saya. Saya menggunakan Windows XP x32 dengan DirectX 9.0c. Karena rendering aktual untuk WPF dilakukan dengan DirectX, ini bisa berpengaruh. Saya sudah mengaktifkan anti-aliasing untuk XP dengan entri registri berikut:

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

Namun, mematikannya dengan pengaturan ini tidak berpengaruh pada gambar. Saya pikir ini hanya efek 3D Viewports.

Akhirnya, saya menemukan bahwa pengaburan terjadi dengan teks TextBlocks serta gambar. Dan pengaburan hanya terjadi pada beberapa blok teks dan gambar, tidak semuanya.

segera
sumber
3

Saya telah menemukan bahwa tidak ada kombinasi dari solusi yang disarankan yang dapat menyembuhkan masalah gambar saya yang tampak acak. Saya suka banyak orang lain tidak dapat memutakhirkan ke .net 4 untuk menggunakan UseLayoutRenderingproperti.

Apa yang saya temukan berhasil:

  • Pastikan dimensi gambar [asli] Anda adalah kelipatan dari 2. Hal ini tampaknya mencegah beberapa masalah penskalaan gambar yang funky.
  • Kadang-kadang saya juga menemukan bahwa menyesuaikan margin pada gambar dengan piksel atau 2 dapat mencegah masalah.
Jahhai
sumber
1

Pikiran pertama saya, membaca pertanyaan, adalah Anda terlalu banyak meledakkan gambar, tetapi tampaknya tidak demikian halnya dengan melihat gambar yang Anda miliki dari aplikasi tersebut.

Pikiran kedua adalah palet warna, tetapi dengan warna hitam sebagai salah satu warna yang tidak ditampilkan dengan benar, ini tidak mungkin.

Jika Anda dapat sepenuhnya mengesampingkan dua di atas, saya saat ini bingung.

Sebagai percobaan, Anda dapat mencoba format grafis lain, tetapi PNG seharusnya baik-baik saja. Saya harus memikirkannya lagi untuk mendapatkan jawaban yang lebih baik.

Gregory A Beamer
sumber
1
+1 untuk menangkal suara negatif yang tidak beralasan karena saya pikir Anda menawarkan beberapa saran yang masuk akal dan hanya berusaha membantu dan yang paling penting tidak ada yang salah dengan saran Anda.
jpierson
1

Saya sudah mencoba menggunakan RenderOptions.BitmapScalingMode = HighQuality, sepertinya menyebabkan beberapa masalah di Windows 8.1, jadi yang saya lakukan adalah menjalankannya melalui alat yang disebut PngOut.exe

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

Yang mengurangi header png, dan juga mengurangi ukuran, tetapi tanpa mengubah kualitas gambar.

Dan sekarang semua gambar saya sempurna! :-)

MMM
sumber