nayuki / QR-Code-generator

High-quality QR Code generator library in Java, TypeScript/JavaScript, Python, Rust, C++, C.

Home Page:https://www.nayuki.io/page/qr-code-generator-library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UE5 Integration Hints

ffreality opened this issue · comments

These are not issues but in order to integrate this library to Unreal Engine 5, we have to know some tricks/hints.
So, I would like to share them because as I see, our ecosystem use this library very much.

Margin/border has to be like this.
Given sample from another issue #107 won't work with UE5 because UE5 doesn't accept negative index for array bounds.
Application just crashes.

(This is for C++)

int32 Margin = Border * 2;
TArray<FColor> QR_Pixels_Raw;
QR_Pixels_Raw.Init(BlackColor, (QRSize + Margin) * (QRSize + Margin));
            
for (int32 x = 0; x < QRSize + 0; x++)
{
    for (int32 y = 0; y < QRSize + 0; y++)
    {
        int32 Index_Pixel = ((x + Border) + (y + Border) * (QRSize + Margin));
        FColor EachPixel = QRCode.getModule(x, y) ? WhiteColor : BlackColor;
        QR_Pixels_Raw[Index_Pixel] = EachPixel;
    }
}

WhiteColor and BlackColor is an Unreal Engine 5 FColor Struct (BGRA8) and TArray is std::vector's equivalent.
They are my function arguments and I can change their values to create colorful QRs.

Other samples from internet use SetNumZeroEd for TArray allocation but in this case, it just creates black border. I use Init. So, I can change border color, too. If developers want to use generated QRs with only cameras, they don't have to use same color with BlackColor. But if developers want to access texture buffer and decode it with programatically (for example with ZXing), border color has to be same with BlackColor.

Also we have to resize image. Because UE5 generates too small textures.
(Unreal Engine 5 Nayuki QR Encode Test string generates roughly 37x37 pixel if we want to use QRCode.getSize())

TArray<FColor> QR_Pixels_Resized;
QR_Pixels_Resized.SetNumZeroed(Resolution.X * Resolution.Y);
FImageUtils::ImageResize(QRSize + Margin, QRSize + Margin, QR_Pixels_Raw, Resolution.X, Resolution.Y, QR_Pixels_Resized, false);

I put all QR generation functions in AsyncTask. Only texture and resize functions are in GameThread. So, there is no performance impact.

Thanks for sharing your knowledge!