Partilhar via


Como aplicar transformações 2D

Observação

Para aplicativos no Windows 10, recomendamos o uso de APIs Windows.UI.Composition em vez de DirectComposition. Para saber mais, veja Modernizar seu aplicativo da área de trabalho usando a camada Visual.

Este tópico demonstra como aplicar transformações 2D a um visual usando o Microsoft DirectComposition. O exemplo neste tópico aplica um grupo de transformações que:

  1. Rode o visual em 180 graus.
  2. Amplie a imagem para três vezes o seu tamanho original.
  3. Traduza (mova) o visual 150 pixels para a direita de sua posição original.

As capturas de tela a seguir mostram o visual antes e depois de aplicar as transformações 2D.

Resultado da aplicação de um grupo de transformações 2D a um visual

O que precisa de saber

Tecnologias

Pré-requisitos

  • C/C++
  • Microsoft Win32
  • Modelo de objeto componente (COM)

Instruções

Etapa 1: Inicializar objetos DirectComposition

  1. Crie o objeto de dispositivo e o objeto de destino de composição.
  2. Crie um visual, defina seu conteúdo e adicione-o à árvore visual.

Para obter mais informações, consulte Como inicializar o DirectComposition.

Etapa 2: Criar a matriz de grupo de transformação

IDCompositionTransform *pTransforms[3];

Etapa 3: Criar os objetos de transformação, definir suas propriedades e adicioná-los à matriz de grupo de transformação

  1. Use os métodos IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransforme ::CreateTranslateTransform para criar os objetos de transformação.
  2. Use as funções de membro do IDCompositionRotateTransform, IDCompositionScaleTransforme IDCompositionTranslateTransform interfaces para definir as propriedades das transformações.
  3. Copie os ponteiros da interface de transformação para a matriz do grupo de transformação.
IDCompositionRotateTransform *pRotateTransform = nullptr;
IDCompositionScaleTransform *pScaleTransform = nullptr;
IDCompositionTranslateTransform *pTranslateTransform = nullptr;
IDCompositionTransform *pTransformGroup = nullptr;

// Create the rotate transform.
hr = pDevice->CreateRotateTransform(&pRotateTransform);

if (SUCCEEDED(hr))
{
    // Set the center of rotation to the center point of the visual.
    hr = pRotateTransform->SetCenterX(BITMAP_WIDTH/2.0f);
    
    if (SUCCEEDED(hr)) {
        hr = pRotateTransform->SetCenterY(BITMAP_HEIGHT/2.0f);
    }

    // Set the rotate angle to 180 degrees.
    if (SUCCEEDED(hr)) {
        hr = pRotateTransform->SetAngle(180.0f);
    }

    // Add the rotate transform to the transform group array.
    pTransforms[0] = pRotateTransform;

    // Create the scale transform.
    if (SUCCEEDED(hr)) {
        hr = pDevice->CreateScaleTransform(&pScaleTransform);
    }
}

if (SUCCEEDED(hr))
{
    // Set the scaling origin to the upper-right corner of the visual.
    hr = pScaleTransform->SetCenterX(0.0f);
    if (SUCCEEDED(hr)) {
        hr = pScaleTransform->SetCenterY(0.0f);
    }

    // Set the scaling factor to three for both the width and height. 
    if (SUCCEEDED(hr)) {
        hr = pScaleTransform->SetScaleX(3.0f);
    }
    if (SUCCEEDED(hr)) {
        hr = pScaleTransform->SetScaleY(3.0f);
    }

    // Add the scale transform to the transform group array.
    pTransforms[1] = pScaleTransform;

    // Create the translate transform.
    if (SUCCEEDED(hr)) {
        hr = pDevice->CreateTranslateTransform(&pTranslateTransform);
    }
}

if (SUCCEEDED(hr))
{
    // Move the visual 150 pixels to the right.
    hr = pTranslateTransform->SetOffsetX(150.0f);
    if (SUCCEEDED(hr)) {
        hr = pTranslateTransform->SetOffsetY(0.0f);
    }

    // Add the translate transform to the transform group array.
    pTransforms[2] = pTranslateTransform;
}

Etapa 4: Criar o objeto de grupo de transformação

Chame o IDCompositionDevice::CreateTransformGroup método para criar o objeto de grupo de transformação.

if (SUCCEEDED(hr))
{
    // Create the transform group.
    hr = pDevice->CreateTransformGroup(pTransforms, 3, &pTransformGroup);
}

Etapa 5: Aplicar o objeto de grupo de transformação ao visual

Utilize o método IDCompositionVisual::SetTransform para associar a propriedade Transform do visual ao objeto de grupo transform.

if (SUCCEEDED(hr))
{
    // Apply the transform group to the visual.
    hr = pVisual->SetTransform(pTransformGroup);
}

Passo 6: Confirmar a composição

Chame o método IDCompositionDevice::Commit para confirmar as atualizações do visual no DirectComposition para processamento. O resultado da aplicação do grupo de transformações 2D aparece na janela de destino.

if (SUCCEEDED(hr))
{
    // Commit the composition.
    hr = pDevice->Commit();
}

Etapa 7: Liberar os objetos DirectComposition

Certifique-se de liberar o grupo de objetos de transformação 2D quando não precisar mais deles. O exemplo a seguir chama a macro definida pela aplicação SafeRelease para liberar os objetos de transformação.

// Release the transform objects.
for (int i = 0; i < 3; i++)
{
    SafeRelease(&pTransforms[i]);
}

Lembre-se também de liberar o objeto do dispositivo, o objeto de destino da composição e os elementos visuais antes que o aplicativo seja encerrado.

Exemplo completo

#define BITMAP_WIDTH  80.0
#define BITMAP_HEIGHT 80.0

HRESULT DemoApp::ApplyTransformGroup(IDCompositionDevice *pDevice, 
                                     IDCompositionVisual *pVisual)
{
    HRESULT hr = S_OK;

    if (pDevice == nullptr || pVisual == nullptr)
        return E_INVALIDARG; 
    
    IDCompositionTransform *pTransforms[3];

    IDCompositionRotateTransform *pRotateTransform = nullptr;
    IDCompositionScaleTransform *pScaleTransform = nullptr;
    IDCompositionTranslateTransform *pTranslateTransform = nullptr;
    IDCompositionTransform *pTransformGroup = nullptr;

    // Create the rotate transform.
    hr = pDevice->CreateRotateTransform(&pRotateTransform);

    if (SUCCEEDED(hr))
    {
        // Set the center of rotation to the center point of the visual.
        hr = pRotateTransform->SetCenterX(BITMAP_WIDTH/2.0f);
        
        if (SUCCEEDED(hr)) {
            hr = pRotateTransform->SetCenterY(BITMAP_HEIGHT/2.0f);
        }

        // Set the rotate angle to 180 degrees.
        if (SUCCEEDED(hr)) {
            hr = pRotateTransform->SetAngle(180.0f);
        }

        // Add the rotate transform to the transform group array.
        pTransforms[0] = pRotateTransform;

        // Create the scale transform.
        if (SUCCEEDED(hr)) {
            hr = pDevice->CreateScaleTransform(&pScaleTransform);
        }
    }

    if (SUCCEEDED(hr))
    {
        // Set the scaling origin to the upper-right corner of the visual.
        hr = pScaleTransform->SetCenterX(0.0f);
        if (SUCCEEDED(hr)) {
            hr = pScaleTransform->SetCenterY(0.0f);
        }

        // Set the scaling factor to three for both the width and height. 
        if (SUCCEEDED(hr)) {
            hr = pScaleTransform->SetScaleX(3.0f);
        }
        if (SUCCEEDED(hr)) {
            hr = pScaleTransform->SetScaleY(3.0f);
        }

        // Add the scale transform to the transform group array.
        pTransforms[1] = pScaleTransform;

        // Create the translate transform.
        if (SUCCEEDED(hr)) {
            hr = pDevice->CreateTranslateTransform(&pTranslateTransform);
        }
    }

    if (SUCCEEDED(hr))
    {
        // Move the visual 150 pixels to the right.
        hr = pTranslateTransform->SetOffsetX(150.0f);
        if (SUCCEEDED(hr)) {
            hr = pTranslateTransform->SetOffsetY(0.0f);
        }

        // Add the translate transform to the transform group array.
        pTransforms[2] = pTranslateTransform;
    }

    if (SUCCEEDED(hr))
    {
        // Create the transform group.
        hr = pDevice->CreateTransformGroup(pTransforms, 3, &pTransformGroup);
    }

    if (SUCCEEDED(hr))
    {
        // Apply the transform group to the visual.
        hr = pVisual->SetTransform(pTransformGroup);
    }

    if (SUCCEEDED(hr))
    {
        // Commit the composition.
        hr = pDevice->Commit();
    }

    // Release the transform objects.
    for (int i = 0; i < 3; i++)
    {
        SafeRelease(&pTransforms[i]);
    }

    // Release the transform group pointer.
    SafeRelease(&pTransformGroup);

    return hr;
}

transforma