Why is the Item picture uploaded to Business Central not as clear as the local one (looks blurry)? Is there any way out of this?

Dynamics 365 Business Central

Hi, Readers.
I was asked a very interesting question yesterday, why is the Item picture uploaded to Business Central not as clear as the local one (looks blurry)?
For example, like the following: The one on the left is the original picture, and the one on the right is on the Item Card after uploading BC. (Although this has been compressed again in my blog, you should still be able to see a significant difference)

But if you choose Export to download the item picture, the original size (resolution) of the image will be exported.

Why? The reason is very simple. What is displayed in Item Picture (346, CardPart) is not the original picture, but the thumbnail generated by the system.
We briefly mentioned this when discussing how to show/display picture thumbnails on the list page, but this time we will discuss it in depth.

As you know, Media or MediaSet data type is currently used to save pictures of Item, Customer, Vendor and other data. Using the Media or MediaSet data type provides better performance than using a BLOB data type and is more flexible in its design. With a BLOB data type, each time the media is rendered in the client, it’s retrieved from the SQL database server, which requires extra bandwidth and affects performance. With the Media and MediaSet data types, the client uses media ID to cache the media data, which in turn improves the response time for rendering the media in the user interface. More details: Working With Media on Records

There are two very important tables here, 2000000184 Tenant Media and 2000000185 Tenant Media Thumbnails.

Imported media is stored as an object in the system table 2000000184 Tenant Media of the tenant database. Each media object is assigned a unique identifier (ID). The original size (resolution 1195*2689) is saved here.

PS: The thumbnails in Content are only displayed on the page. If you open the table directly, corrupted images will be displayed.

Source code: If you want to test, you can use the code below directly.

page 50100 "Tenant Media List"
{
    ApplicationArea = All;
    Caption = 'Tenant Media List';
    PageType = List;
    SourceTable = "Tenant Media";
    UsageCategory = Lists;

    layout
    {
        area(content)
        {
            repeater(General)
            {
                field(ID; Rec.ID)
                {
                    ToolTip = 'Specifies a unique identifier for this media.';
                }
                field("Media Content"; Rec.Content)
                {
                    ToolTip = 'Specifies the picture of the media.';
                }
                field("Mime Type"; Rec."Mime Type")
                {
                    ToolTip = 'Specifies the file type';
                }
                field(Height; Rec.Height)
                {
                    ToolTip = 'Specifies the value of the Height field.';
                }
                field(Width; Rec.Width)
                {
                    ToolTip = 'Specifies the value of the Width field.';
                }
                field(SystemCreatedAt; Rec.SystemCreatedAt)
                {
                    ToolTip = 'Specifies the date and time when the record was created.';
                }
            }
        }
    }
}

When the original picture is saved in 2000000184 Tenant Media, the system will automatically generate the thumbnails according to the current page and save them in the system table 2000000185 Tenant Media Thumbnails with same Media ID. For example, for the picture I just uploaded, it generated three thumbnails. One is in original proportions (160*360), the other two are square (240*240 and 70*70).

PS:
1. Same as above, if you want to see the thumbnails in 2000000185 Tenant Media Thumbnails, you need to create a new list page.

Source code:

page 50101 "Tenant Media Thumbnail List"
{
    ApplicationArea = All;
    Caption = 'Tenant Media Thumbnail List';
    PageType = List;
    SourceTable = "Tenant Media Thumbnails";
    UsageCategory = Lists;

    layout
    {
        area(content)
        {
            repeater(General)
            {
                field(ID; Rec.ID)
                {
                    ToolTip = 'Specifies the value of the ID field.';
                }
                field("Media ID"; Rec."Media ID")
                {
                    ToolTip = 'Specifies the value of the Media ID field.';
                }
                field("Media Content"; Rec.Content)
                {
                    ToolTip = 'Specifies the value of the Content field.';
                }
                field("Mime Type"; Rec."Mime Type")
                {
                    ToolTip = 'Specifies the value of the Mime Type field.';
                }
                field(Height; Rec.Height)
                {
                    ToolTip = 'Specifies the value of the Height field.';
                }
                field(Width; Rec.Width)
                {
                    ToolTip = 'Specifies the value of the Width field.';
                }
                field(SystemCreatedAt; Rec.SystemCreatedAt)
                {
                    ToolTip = 'Specifies the value of the SystemCreatedAt field.';
                }
            }
        }
    }
}

2. This is the same for Customer Picture, Vendor Picture, etc.

The thumbnails of two squares is very simple and is used in Tall Tiles and Tiles views.

The one remaining thumbnail of the original proportions is used in the factbox that displays the picture on the card.

The above is the reason for this problem. The advantage of this is that the system does not need to read the original size image when opening the page. If the original image is large, it will affect the speed of opening the page and affect the system performance.

But if the client can’t take it, is there any way out of this? There is a very simple way. Instead of using Media or MediaSet data type, just use Blob Data Type, like Picture in the Company Information page.

Let’s see a simple test. Add a new Blob field to the Item table, then add a picture from the Item Card page and display it in the Item Picture Factbox.

It can be seen that the Blob type picture is clearer than the Media type picture above. This is because the Blob Data Type does not use the thumbnail, but the original image.

Source code:

tableextension 50113 ItemExt extends Item
{
    fields
    {
        field(50100; ItemPicture; Blob)
        {
            Caption = 'Item Picture';
            Subtype = Bitmap;
            DataClassification = CustomerContent;
        }
    }
}
pageextension 50100 ItemCardExt extends "Item Card"
{
    layout
    {
        addafter(Warehouse)
        {
            group(NewItemPicture)
            {
                Caption = 'Item Picture Group';
                field(ZYItemPicture; Rec.ItemPicture)
                {
                    Caption = 'Item Picture';
                    ShowCaption = false;
                    MultiLine = true;
                    ApplicationArea = All;

                    trigger OnValidate()
                    begin
                        CurrPage.Update();
                    end;
                }
            }
        }
    }
}
pageextension 50112 ItemPictureExt extends "Item Picture"
{
    layout
    {
        addafter(Picture)
        {
            field(ItemPicture; Rec.ItemPicture)
            {
                Caption = 'Item Picture';
                ShowCaption = false;
                ApplicationArea = All;
            }
        }
    }
}

This solves the problem. But personally I don’t recommend it because it goes back to the original NAV style and doesn’t provide better performance😑. Okay, finally, let me optimize the solution, automatically update this new Blob field when importing Item Picture, and clear it at the same time when deleting it.
Test video: Looks good. (Just for comparison I show two pictures, you can hide the original Picture field on page 346 “Item Picture”)

Give it a try!!!😁

Source code:

tableextension 50113 ItemExt extends Item
{
    fields
    {
        field(50100; ItemPicture; Blob)
        {
            Caption = 'Item Picture';
            Subtype = Bitmap;
            DataClassification = CustomerContent;
        }
    }
}

pageextension 50112 ItemPictureExt extends "Item Picture"
{
    layout
    {
        addafter(Picture)
        {
            field(ItemPicture; Rec.ItemPicture)
            {
                Caption = 'Item Picture';
                ShowCaption = false;
                ApplicationArea = All;
            }
        }
    }
}

codeunit 50112 MyCodeunit
{
    [EventSubscriber(ObjectType::Page, Page::"Item Picture", OnImportFromDeviceOnAfterModify, '', false, false)]
    local procedure OnImportFromDeviceOnAfterModify(var Item: Record Item);
    var
        ItemTenantMedia: Record "Tenant Media";
        InStr: InStream;
        OutStr: OutStream;
    begin
        if Item.Picture.Count > 0 then begin
            ItemTenantMedia.Get(Item.Picture.Item(1));
            ItemTenantMedia.CalcFields(Content);
            ItemTenantMedia.Content.CreateInStream(InStr, TextEncoding::UTF8);
            Item.ItemPicture.CreateOutStream(OutStr);
            CopyStream(OutStr, InStr);
            Item.Modify(true);
        end;
    end;

    [EventSubscriber(ObjectType::Page, Page::"Item Picture", OnAfterDeleteItemPicture, '', false, false)]
    local procedure OnAfterDeleteItemPicture(var Item: Record Item);
    begin
        Clear(Item.ItemPicture);
        Item.Modify(true);
    end;
}

END

Hope this will help.

Thanks for reading.

ZHU

コメント

Copied title and URL