2009-01-23 12 views
7

Szukam konwersji pikseli na cale i na odwrót. Rozumiem, że potrzebuję DPI, ale nie jestem pewien, jak uzyskać te informacje (np. Nie mam obiektu Graphics, więc to nie jest opcja).Konwertuj piksele na cale i na odwrót w C#

Czy istnieje sposób?

+0

DPI czego? ekran? drukarka? ...? –

Odpowiedz

7

Na urządzeniu wideo każda odpowiedź na to pytanie zwykle nie jest bardzo dokładna. Najprostszym przykładem użycia, aby zobaczyć, dlaczego tak jest, jest projektor. Rozdzielczość wyjściowa wynosi na przykład 1024x768, ale czułość zależy od odległości ekranu od projektora. Na przykład WPF zawsze zakłada rozdzielczość 96 DPI na urządzeniu wideo.

Zakładając, że wciąż potrzebujesz odpowiedzi, bez względu na dokładność, a nie masz obiektu Grafiki, możesz utworzyć go z ekranu za pomocą jakiegoś P/Invoke i uzyskać od niego odpowiedź.

Single xDpi, yDpi; 

IntPtr dc = GetDC(IntPtr.Zero); 

using(Graphics g = Graphics.FromHdc(dc)) 
{ 
    xDpi = g.DpiX; 
    yDpi = g.DpiY; 
} 

if (ReleaseDC(IntPtr.Zero) != 0) 
{ 
    // GetLastError and handle... 
} 


[DllImport("user32.dll")] 
private static extern IntPtr GetDC(IntPtr hwnd);  
[DllImport("user32.dll")] 
private static extern Int32 ReleaseDC(IntPtr hwnd); 
+0

Na podstawie tego, o co prosił użytkownik, powinno to być zaakceptowaną odpowiedzią. – epotter

6

Nie ma, fizycznie, żadnej realnej drogi bez znajomości DPI. Piksele są dyskretne, cale nie są, jeśli mówisz cale na monitorze, musisz znać (przynajmniej) rozdzielczość (i proporcje pikseli) i rozmiar widocznego obszaru monitora, aby obliczyć DPI . Rozdzielczość jest zazwyczaj możliwa do pobrania (nie jestem programistą C# lub .NET, więc nie mogę ci tam pomóc), ale rozmiar monitora zwykle nie jest dostępny. Jeśli oszacowanie jest wystarczająco dobry, wtedy użytkownik wprowadź rozmiar monitora (czyli 21" lub cokolwiek) i rozwiązać za DPI:

(resX/DPI)^2 + (resY/DPI)^2 = screenDiagonal^2 

daje (zakładając, że wiesz, że przekątna i rozdzielczość)

DPI = sqrt(resX^2+resY^2)/screenDiagonal 

To tylko szacunek, ponieważ monitory nigdy nie są dokładnie 21 "(.. lub cokolwiek innego), a proporcje pikseli rzadko wynoszą dokładnie 1: 1.

Jeśli mówisz o calach na papierze, to całkiem naturalnie musisz znać DPI twojej drukarki (lub, dokładniej, aktualne ustawienia drukarki).

+0

Biorąc pod uwagę, że nie mam dostępu do obiektu Graphics, w jaki sposób obliczyć DPI? – AngryHacker

+0

Rozwiąż równanie dla DPI, zakładając, że reszta jest znana. – falstro

+0

Skąd mam wiedzieć długość przekątnej monitora? Moja aplikacja będzie działać na komputerach, nad którymi nie sprawuję kontroli. – AngryHacker

1

Możesz utworzyć obiekt graficzny po prostu przez wywołanie this.CreateGraphics() (lub bardziej ogólnie Control.CreateGraphics()), a następnie użyj właściwości DpiX i DpiY, jak się wydaje. Pamiętaj tylko, aby wyrzucić obiekt graficzny po jego utworzeniu (najlepiej za pomocą instrukcji Using).

Jeśli nie korzystasz z WinForms, poinformuj nas o tym, jaka to aplikacja.

+0

Nie mogę. Piszę kod w pliku z kodem z arkusza raportu ActiveReports. Nie ma tych właściwości. – AngryHacker

+0

Podał, że używa WPF, który nie jest WinForm. Korzystanie z dwóch razem może spowodować poważne bóle głowy. – mmr

+0

@ mmr: Nie, nie powiedział, że używa WPF. W rzeczywistości odniesienie do "grafiki" zdaje się silnie implikować WinForm. Dziękuję za głosowanie w dół. – Noldorin

Powiązane problemy