문제

나는 응용 프로그램을 생성하는 메타파일(emf 형식).사용 참조 장치(aka 화면)를 렌더링 이러한 메타파일,그래서 DPI 의 메타파일의 변화에 따라 어떤 기계 코드에서 실행.

말하자 나의 코드입하려는 메타파일을 만들는 8.5in x11.를 사용하여 개발 워크스테이션 참고로 나는 끝나는 EMF 가

  • 는 rclFrame 의{ 0, 0, 21590, 27940 } (의 크기는 메타파일에서의 수천의 mm)
  • a szlDevice 의{1440,900}(차원의 참조 장치를 픽셀 단위)
  • a szlMillimeters 의{416,260}(차원의 참조 장치,mm)

그래 rclFrame 는 크기의 EMF 야

  • 21590/2540=8.5 에 wide
  • 27940/2540=11 에서 높

오른쪽에있다.이 정보를 사용하여,우리는 확인할 수 있습 물리적 DPI 의 내 모니터,는 경우에,너무 나의 수학은 오른쪽:

  • (1440*25.4)/416=87.9231 수평 dpi
  • (900*25.4)/260=87.9231 수직 dpi

문제

는 아무거나 다시 재생하는 이--메타파일 EMF 을 PDF 변환,요약 페이지를 오른쪽 클릭 EMF 에서 윈도우 탐색기 등을 자를 계산 DPI 값을 표시하 87 대신 87.9231(도 88 것 괜찮습니다).

이 결과는 페이지에서 육체적으로 크기로 8.48x10.98 에서 사용하여(87dpi)대 8.5in x11 에서 사용하여(88dpi)면 메타파일은 재생됩니다.

  • 그것은 변경할 수 DPI 의 참고도록 장치에 저장된 정보에 대한 메타파일을 계산하는 데 사용되는 DPI 제공하는 좋은 정수?
  • 을 만들 수 있습니 내 자신 장치의 컨텍스트를 지정 DPI?또는 나는 진짜로 사용하는 프린터는 그렇게 하라고 하셨을까?

감사에 대한 어떤 통찰이다.

도움이 되었습니까?

해결책

Windows가 모니터의 물리적 크기를 어떻게 알고 있는지 궁금합니다. 어딘가에 구성을 변경 했어야합니까? 아마도 당신은 그것을 멋지게 나누는 더 편리한 값으로 변경할 수 있습니다.

이름으로 암시 된 바와 같이, "장치 컨텍스트"는 시스템 장치에 연결되어야합니다. 그러나 이것은 하드웨어 드라이버 일 필요는 없으며 PDF Writer Print 드라이버와 같은 장치 에뮬레이터 일 수 있습니다. 임의의 DPI를 설정할 수있는 적어도 하나를 보았습니다.

다른 팁

나는 지금보다 더 많이 배웠 나는 걱정에 대해 알고 있었 메타파일.

1.의 일부 Metafile 클래스의 생성자를 오버로드를 제대로 작업하고 운영할 것이 잘린 DPI 값입니다.

다음 사항을 고려하십시오:

protected Graphics GetNextPage(SizeF pageSize)
{
    IntPtr deviceContextHandle;
    Graphics offScreenBufferGraphics;
    Graphics metafileGraphics;
    MetafileHeader metafileHeader;

    this.currentStream = new MemoryStream();
    using (offScreenBufferGraphics = Graphics.FromHwnd(IntPtr.Zero))
    {
        deviceContextHandle = offScreenBufferGraphics.GetHdc();
        this.currentMetafile = new Metafile(
            this.currentStream,
            deviceContextHandle,
            new RectangleF(0, 0, pageSize.Width, pageSize.Height),
            MetafileFrameUnit.Inch,
            EmfType.EmfOnly);

        metafileGraphics = Graphics.FromImage(this.currentMetafile);

        offScreenBufferGraphics.ReleaseHdc();
    }

    return metafileGraphics;
}

는 경우 전달 SizeF 의{8.5,11},할 수 있습을 얻을 것으로 예상 MetafilerclFrame 의{21590,27940}.인치로 변환하여 밀리미터는 것은 어렵지 않다.하지만 당신은 아마 하지 않습니다.에 따라 해상도 GDI+,그것은 보인다,사용할 것이 잘린 DPI 값을 변환하는 경우 인치 매개 변수입니다.바로 그것을 얻으려면,나는 그것을 자신을 할 수 백분의 밀리미터이 GDI+만 통과 이후는 방법은 기본적으로 저장되는 메타파일의 헤더:

this.currentMetafile = new Metafile(
    this.currentStream,
    deviceContextHandle,
    new RectangleF(0, 0, pageSize.Width * 2540, pageSize.Height * 2540),
    MetafileFrameUnit.GdiCompatible,
    EmfType.EmfOnly);

라운딩 오류#1 해결--의 rclFrame 의 메타파일 지금은 올바른 것입니다.

2.DPI 에 Graphics 인스턴스에 기록 Metafile 고 있다.

metafileGraphics 변수 설정에 의해 호출 Graphics.FromImage() 에 metafile?만,그것은 보인다는 Graphics 인스턴스는 항상 DPI96dpi.(나는 생각했다 경우,항상 설정 논리 DPI,지 물리적 하나입니다.)

당신이 상상할 수 있는 환희는 계속된다면 당신은 그리기에 Graphics 인스턴스에 따라 운영 96dpi 및 기록 Metafile 인스턴스가 있는 87.9231dpi"기록"헤더에.(말이"기록"기 때문에 그것의 계산에서 다른 값이다.) 메타파일의"pixels"(기억 GDI 명령에 저장된 메타파일에서 지정한 픽셀 이)더 크고,그래서 당신은 저주와 속삭이 왜 귀하의 전화를 그리는 뭔가 중 하나 인치되고 끝나고 무언가 넘습니다.

이 솔루션은 규모로 Graphics 인스턴스:


metafileGraphics = Graphics.FromImage(this.currentMetafile);
metafileHeader = this.currentMetafile.GetMetafileHeader();
metafileGraphics.ScaleTransform(
    metafileHeader.DpiX / metafileGraphics.DpiX,
    metafileHeader.DpiY / metafileGraphics.DpiY);

지 않는 야유가?하지만 그것은 작동하는 것 같다.

"올림"error#2 해결--말할 때 그가"에서 1 인치"88dpi,는 픽셀의 것이 좋$%$^!기록으로 픽셀#88.

3. szlMillimeters 할 수 있는 격렬하게 변화;원격 데스크톱의 원인은 많은 재미 있습니다.

그래서,우리가 발견한(당시의 답변)는,때로는,윈도우 쿼리 EDID 의하 모니터링하고 실제로 알고 있는 것이 얼마나 큰 육체적으로 있습니다.GDI+유용하게 사용하는 이(HORZSIZE 등)를 작성할 때에 szlMillimeters 을 제공합니다.

이제 당신이 집에 가서 이것을 디버깅하는 코드는 원격 데스크톱.말하는 가정용 컴퓨터에 발생하 16:9 와이드스크린 모니터링합니다.

분명히,윈도우 쿼리할 수 없습니다 EDID 의 원격 디스플레이.그래서 사용하는 오래된 기본 320x240mm,는 것을 제외하고,잘 일어나는 것을 4:3 화면 비율,지금은 정확히 동일한 코드를 생성하는 메타파일 디스플레이에 아마 정사각형이 아닌 육체적 픽셀:수평 DPI 및 수직 DPI 는 다르다,그리고 내가 기억할 수 없는 마지막으로 나는 일어난다.

나에 대한 해결 방법에 대해 이제는:"글쎄,그것을 실행하지 않는 원격 데스크톱에서."

4.EMF 을 PDF 도구는 내가 사용되었던 반올림하면 오류 보고 rclFrame 헤더입니다.

이것이 주요 원인이 내 문제의 유발 이 질문입니다.내장 메타파일이었다"올바른"모두 함께(만,올바른 후 나는 고정된 첫 번째 두 가지 문제),및 모든 이 검색에 대한 창조"고해상도"메타파일되었다.그것은 사실 어떤 충실도 잃 기록할 때에는 메타파일에 저해상도 디스플레이 장치;기 때문이다 GDI 명령어에서 지정된 메타파일에서 지정된 픽셀이 있습니다.문제가 되지 않습니다 그것은 벡터 포맷하고 확장 할 수 있습니다 위로 또는 아래로,어떤 정보가 분실 는 동안 실제적인 기록 때 GDI+하기로 결정하는"픽셀은"스냅 동작습니다.

연락 공급업체 및 그들은 나에게 정정 버전입니다.

라운딩 오류#3 해결합니다.

5.는'요약'창에서 윈도우 탐색기에게 잘라 값을 표시할 때 계산 DPI.

그것은 그냥 일이 잘 나타내는 값이 동일한 잘못된 가치는 EMF 을 PDF 도구를 사용하여 내부적으로 합니다.이외에도,이 특질 기여하지 않는 것도 의미를 논의한다.

결론

이후 나의 질문에 대한 futzing DPI 장치의 컨텍스트 마크의 좋은 대답합니다.

WXP에서 항상 120dpi로 실행됩니다 (큰 글꼴)은 Metafilegraphics.dpix가 120을 반환합니다.

EMF 파일은 DPI가 참조 컨텍스트의 내용을 기록하는 것으로 보이지 않습니다 (이 경우 120, 대부분의 다른 사람들의 경우 96).

일을 더 흥미롭게 만들기 위해, 300dpi로 설정된 메모리 비트 맵에 드로잉을 통해 EMF를 만들 수 있습니다. 이 경우 스케일링 계수가 300이어야하며 모니터 (86.x) 또는 Windows (120)가 사용하는 것이 아닌 것이 아닙니다.

요약 페이지의 값이 잘못된 것 같습니다. 그들은 다음과 같이 계산됩니다.

Size = round(precize_size)+1
Resolution = trunc(precize_resolution)

예비 값은 반올림 또는 잘림없이 계산됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top