2015-02-01 8 views
1

이미지 (JPG 테스트)를 읽고, 클리핑 사각형 영역을 지정하고 "클리핑 된"영역을 파일에 쓰는 코드는 다음과 같습니다.파일 - 잘못된 해상도로 IWICBtmap 쓰기

내 테스트 이미지는 320x240 픽셀 @ 300dpi입니다. 내가 모든 지시에서 그것을 읽었을 때 그것이 그 크기라고 말하지만, 내가 그것을 쓸 때 결과 이미지는 102 x 76이고 파일 속성을 보면 아무런 H/V 해상도도 보지 못했습니다.

320/102 = 3.1372 및 300/96 = 3.125 화면 해상도와 이미지의 차이가 있습니까?

IWICBitmap을 쓰는이 전체 주제는 처음부터 권투 시합이었습니다. 왜 이렇게 어려운거야?

감사 무리

IWICImagingFactory *pImageFactory = GfxAgent::WICImagingFactory::GetInstance().GetFactory(); 

    D2D1_SIZE_U sizeFrame = D2D1::SizeU(imageRect.Width(), imageRect.Height()); 

    CComPtr<IWICBitmap> pWICBitmap; 
    hr = pImageFactory->CreateBitmap(imageRect.Width(), imageRect.Height(), 
     GUID_WICPixelFormat32bppPBGRA, 
     WICBitmapCacheOnLoad, 
     &pWICBitmap 
    ); 

    D2D1_RENDER_TARGET_PROPERTIES rtProps = D2D1::RenderTargetProperties(); 
    rtProps.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED); 
    rtProps.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; 
    rtProps.usage = D2D1_RENDER_TARGET_USAGE_NONE; 

    // define the render target 
    CComPtr<ID2D1RenderTarget> pRenderTarget = 0; 
    hr = m_pDirect2dFactory->CreateWicBitmapRenderTarget(pWICBitmap, rtProps, &pRenderTarget); 

    CComPtr<ID2D1Bitmap> imageS; 
    hr = GfxAgent::ImageUtilities::LoadImageFromFile(pRenderTarget, m_imgPath, 0, 0, 0, &imageS, &resX, &resY); 

    if (hr != S_OK) 
    { 
    } 

    // get format of image we just read 
    D2D1_PIXEL_FORMAT fmt = imageS->GetPixelFormat(); 

    CComPtr<ID2D1Bitmap> imageD; 
    D2D1_SIZE_U bitmapPixelSize = D2D1::SizeU(imageRect.Width(), imageRect.Height()); 

    // create destination image of "clipped" source image 
    hr = pRenderTarget->CreateBitmap(bitmapPixelSize, D2D1::BitmapProperties(
     D2D1::PixelFormat(fmt.format, fmt.alphaMode), 
     (float)resX, (float)resY), &imageD); 

    D2D1_POINT_2U topleft = D2D1::Point2U(0, 0); 
    D2D1_RECT_U srcRect = D2D1::RectU(imageRect.left, imageRect.top, imageRect.right, imageRect.bottom); 
    // get the "clipped" source 
    hr = imageD->CopyFromBitmap(&topleft, imageS, &srcRect); 

    if (hr != S_OK) 
    { 
    } 

    CComPtr<IWICBitmapEncoder> pEncoder; 
    CComPtr<IWICBitmapFrameEncode> pFrame; 
    CComPtr<IWICStream> pStream; 

    WICPixelFormatGUID format = GUID_WICPixelFormat32bppPBGRA; 

    // draw the "clipped" image into the render target (WIC image) 
    if (SUCCEEDED(hr)) { 
     pRenderTarget->BeginDraw(); 
     pRenderTarget->Clear(); 
     pRenderTarget->DrawBitmap(imageD); 
     hr = pRenderTarget->EndDraw(); 
    } 

    // now proceed to write the "clipped" image to a file 
    if (SUCCEEDED(hr)) { 
     hr = pImageFactory->CreateStream(&pStream); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pStream->InitializeFromFilename(MultiByteToUnicode(szNewFileName).c_str(), GENERIC_WRITE); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pImageFactory->CreateEncoder(GUID_ContainerFormatJpeg, NULL, &pEncoder); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pEncoder->Initialize(pStream, WICBitmapEncoderNoCache); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pEncoder->CreateNewFrame(&pFrame, NULL); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->Initialize(NULL); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->SetSize((UINT)imageD->GetSize().width, (UINT)imageD->GetSize().height); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->SetPixelFormat(&format); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->WriteSource(pWICBitmap, NULL); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->Commit(); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pEncoder->Commit(); 
    } 

상세 정보

 D2D1_POINT_2U topleft = D2D1::Point2U(0, 0); 
    D2D1_RECT_U srcRect = D2D1::RectU(imageRect.left, imageRect.top, imageRect.right, imageRect.bottom); 
    // get the "clipped" source 
    hr = imageD->CopyFromBitmap(&topleft, imageS, &srcRect); 

    if (hr != S_OK) 
    { 
    } 

    UINT wD, hD; 
    wD = (UINT)imageD->GetSize().width; 
    hD = (UINT)imageD->GetSize().height; 

imageRect이고 정확한 LTRB =

하지만 복사 한 후 WD = 102, 76 = HD

0,0,320,240

왜? 여기

좀 더 많은 정보를 인

CComPtr<ID2D1Bitmap> imageD; 
    D2D1_SIZE_U bitmapPixelSize = D2D1::SizeU(imageRect.Width(), imageRect.Height()); 

    // create destination image of "clipped" source image 
    hr = pRenderTarget->CreateBitmap(bitmapPixelSize, D2D1::BitmapProperties(
     D2D1::PixelFormat(fmt.format, fmt.alphaMode), 
     (float)resX, (float)resY), &imageD); 

    UINT wD, hD; 
    wD = (UINT)imageD->GetSize().width; 
    hD = (UINT)imageD->GetSize().height; 

bitmapPixelSize가 올바른지 320 X, RESX과 Y가 300

format= DXGI_FORMAT_B8G8R8A8_UNORM 
    alphaMode D2D1_ALPHA_MODE_PREMULTIPLIED 

WD = 102 (240)와 HD = 76 - 왜?

IWICImagingFactory *pImageFactory = GfxAgent::WICImagingFactory::GetInstance().GetFactory(); 

    D2D1_SIZE_U sizeFrame = D2D1::SizeU(imageRect.Width(), imageRect.Height()); 

    CComPtr<IWICBitmap> pWICBitmap; 
    hr = pImageFactory->CreateBitmap(imageRect.Width(), imageRect.Height(), 
     GUID_WICPixelFormat32bppPBGRA, 
     WICBitmapCacheOnLoad, 
     &pWICBitmap 
    ); 

    // sanity check 
    UINT wicW, wicH; 
    pWICBitmap->GetSize(&wicW, &wicH); 

    D2D1_RENDER_TARGET_PROPERTIES rtProps = D2D1::RenderTargetProperties(); 
    rtProps.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED); 
    rtProps.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; 
    rtProps.usage = D2D1_RENDER_TARGET_USAGE_NONE; 

    // define the render target 
    CComPtr<ID2D1RenderTarget> pRenderTarget = 0; 
    hr = m_pDirect2dFactory->CreateWicBitmapRenderTarget(pWICBitmap, rtProps, &pRenderTarget); 

    CComPtr<ID2D1Bitmap> imageS; 
    hr = GfxAgent::ImageUtilities::LoadImageFromFile(pRenderTarget, m_imgPath, 0, 0, 0, &imageS, &resX, &resY); 

    if (hr != S_OK) 
    { 
    } 

    // set new image resolution same as source 
    pWICBitmap->SetResolution(resX, resY); 

    // get format of image we just read 
    D2D1_PIXEL_FORMAT fmt = imageS->GetPixelFormat(); 

    CComPtr<ID2D1Bitmap> imageD; 
    D2D1_SIZE_U bitmapPixelSize = D2D1::SizeU(imageRect.Width(), imageRect.Height()); 

    // create destination image of "clipped" source image 
    hr = pRenderTarget->CreateBitmap(bitmapPixelSize, D2D1::BitmapProperties(
     D2D1::PixelFormat(fmt.format, fmt.alphaMode), 
     (float)resX, (float)resY), &imageD); 

    D2D1_POINT_2U topleft = D2D1::Point2U(0, 0); 
    D2D1_RECT_U srcRect = D2D1::RectU(imageRect.left, imageRect.top, imageRect.right, imageRect.bottom); 
    // get the "clipped" source 
    hr = imageD->CopyFromBitmap(&topleft, imageS, &srcRect); 

    if (hr != S_OK) 
    { 
    } 

    // just a sanity check (pixels NOT DIPS) 
    D2D1_SIZE_U sourcePixelSize = imageS->GetPixelSize(); 
    D2D1_SIZE_U destPixelSize = imageD->GetPixelSize(); 

    CComPtr<IWICBitmapEncoder> pEncoder; 
    CComPtr<IWICBitmapFrameEncode> pFrame; 
    CComPtr<IWICStream> pStream; 

    WICPixelFormatGUID format = GUID_WICPixelFormat32bppPBGRA; 

    // draw the "clipped" image into the render target (WIC image) 
    if (SUCCEEDED(hr)) { 
     pRenderTarget->BeginDraw(); 
     pRenderTarget->Clear(); 
     pRenderTarget->DrawBitmap(imageD); 
     hr = pRenderTarget->EndDraw(); 
    } 

    // now proceed to write the "clipped" image to a file 
    if (SUCCEEDED(hr)) { 
     hr = pImageFactory->CreateStream(&pStream); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pStream->InitializeFromFilename(MultiByteToUnicode(szNewFileName).c_str(), GENERIC_WRITE); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pImageFactory->CreateEncoder(GUID_ContainerFormatJpeg, NULL, &pEncoder); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pEncoder->Initialize(pStream, WICBitmapEncoderNoCache); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pEncoder->CreateNewFrame(&pFrame, NULL); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->Initialize(NULL); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->SetSize(destPixelSize.width, destPixelSize.height); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->SetPixelFormat(&format); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->WriteSource(pWICBitmap, NULL); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pFrame->Commit(); 
    } 

    if (SUCCEEDED(hr)) { 
     hr = pEncoder->Commit(); 
    } 
+0

이것이 어떤 프로그래밍 언어로 도움이 될지 알려주고 있습니다! –

+0

Windows 7 또는 8.1, C++ –

답변

1

ID2D1Bitmap::GetSize

최신 코드는 당신에게 저러나 가져옵니다

는 비트 맵의, 장치 독립적 픽셀 (DIP는)에, 사이즈를 돌려줍니다.

DIP는 1/96 인치입니다. 장치 픽셀의 크기를 검색하려면 ID2D1Bitmap :: GetPixelSize 메서드를 사용합니다.

크기는 320px * 96dpi/px/300dpi = 102.4 개의 기기 독립적 픽셀입니다. Y 축을 따라 동일합니다.

+0

좋습니다. "괜찮은"문구에 대해서는 내 코드와 설명서를 다시 검토 할 것입니다. 감사합니다. 올바른 때 다시보고하겠습니다. –

+0

올바른 변경 사항 (320x240)으로 jpg 파일을 생성하는 변경 사항이 있지만 왼쪽 상단의 102x76처럼 복사 된 이미지가 나타납니다.API 문서의 일부를 읽으면 크기 매개 변수가 너비 또는 높이 또는 픽셀을 매우 구체적으로 지정하지 않습니다. 이 기능을 사용하면 원래 게시물에 업데이트 된 코드가 게시됩니다. –

+0

아마도'imageS'와'imageD'는 다른 DPI입니다. 나는 당신이 SetResolution 호출로 그것을 변경하려하고 있지만 그것이 늦었고 효과가 없다고 생각한다. –

0

나는 다음과 같은 속성

D2D1_RENDER_TARGET_PROPERTIES rtProps = D2D1::RenderTargetProperties(); 
    rtProps.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED); 
    rtProps.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; 
    rtProps.usage = D2D1_RENDER_TARGET_USAGE_NONE; 
    rtProps.dpiX = (float)m_img.GetResolutionX(); 
    rtProps.dpiY = (float)m_img.GetResolutionY(); 

키가 원래 이미지의 해상도를 사용하고있었습니다을 사용 WICBitmap에서 렌더 타겟을 만들 때 원본 이미지의 해상도가 무엇인지 아는을 설정하려고 시도, 생성 나중에 아무것도하지 않았다. 로마는 나에게 "힌트"를주었습니다 - 감사합니다.