1
0
mirror of https://github.com/microsoft/DirectXTex synced 2024-09-18 22:59:54 +00:00
7 TransformImage
Chuck Walbourn edited this page 2022-04-26 18:37:24 -07:00
DirectXTex

Creates a new image by executing a user-supplied function across an input image.

HRESULT TransformImage(
    const Image& image,
    std::function<
        void(XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y)
    > pixelFunc,
    ScratchImage& result );

HRESULT TransformImage(
    const Image* srcImages, size_t nimages, const TexMetadata& metadata,
    std::function<
        void(XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y)
    > pixelFunc,
    ScratchImage& result );

Breaking change notice: In the September 2016 release this function was Transform but this generic name can cause conflicts in some client code so it was renamed TransformImage.

Parameters

pixelFunc: A callback function to invoke for each scanline of the image which outputs the new scanline.

Example

This function performs a colorkey or chromakey transformation setting alpha to 0 (transparent) wherever the color is found and 1 (opaque) otherwise.

ScratchImage result;
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
    [](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y)
{
    static const XMVECTORF32 s_chromaKey = { 0.f, 1.f, 0.f, 0.f };
    static const XMVECTORF32 s_tolerance = { 0.2f, 0.2f, 0.2f, 0.f };

    UNREFERENCED_PARAMETER(y);

    for (size_t j = 0; j < width; ++j)
    {
        XMVECTOR value = inPixels[j];

        if (XMVector3NearEqual(value, s_chromaKey, s_tolerance))
        {
            value = g_XMZero;
        }
        else
        {
            value = XMVectorSelect(g_XMOne, value, g_XMSelect1110);
        }
        outPixels[j] = value;
     }
}, result);
if (FAILED(hr))
    ...

Here is an example for applying a tonemap operator:

XMVECTOR maxLum = XMVectorZero();
HRESULT hr = EvaluateImage(*image.GetImage(0, 0, 0),
    [&](const XMVECTOR* pixels, size_t width, size_t y)
    {
        UNREFERENCED_PARAMETER(y);
        for (size_t j = 0; j < width; ++j)
        {
            static const XMVECTORF32 s_luminance = { 0.3f, 0.59f, 0.11f, 0.f };

            XMVECTOR v = *pixels++;

            v = XMVector3Dot(v, s_luminance);

            maxLum = XMVectorMax(v, maxLum);
        }
    });
if (FAILED(hr))
    ...

maxLum = XMVectorMultiply(maxLum, maxLum);

ScratchImage result;
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
    [](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y)
{
    UNREFERENCED_PARAMETER(y);

    for (size_t j = 0; j < width; ++j)
    {
        XMVECTOR value = inPixels[j];

        XMVECTOR scale = XMVectorDivide(
            XMVectorAdd(g_XMOne, XMVectorDivide(value, maxLum)),
            XMVectorAdd(g_XMOne, value));
        XMVECTOR nvalue = XMVectorMultiply(value, scale);

        value = XMVectorSelect(value, nvalue, g_XMSelect1110);

        outPixels[j] = value;
    }
}, result);
if (FAILED(hr))
    ...

Remarks

The user-supplied function always reads & writes DXGI_FORMAT_R32G32B32A32_FLOAT data in the scanlines.

Block compressed formats are not supported. See Decompress.

This function cannot operate directly on planar format image. See ConvertToSinglePlane for a method for converting planar data to a format that is supported by this routine.