Tijdelijk extra IT-experts nodig?

Neem contact met ons op

Onze expertises

Een betrouwbare partner

ShareValue is Microsoft Solution Partner en SNA-gecertificeerd. Het SNA-keurmerk wordt al jaren aan ShareValue toegekend. Dit keurmerk is ontwikkeld om de risico’s te beperken omtrent keten- en inlenersaansprakelijkheid. Tweemaal per jaar worden wij door een geaccrediteerde inspectie-instelling gecontroleerd, met toekenning van het certificaat als gevolg.

  • Logo MS Solution partner
  • stichtingNormeringArbeid.svg

ShareValue - De standaard voorbij

Meer over ons

Zo werkt ShareValue

  • Experts

    Experts

    Onze experts weten alles van Microsoft 365, .NET, Azure en Front-End.

  • Eigen mensen

    Eigen mensen

    Wij kennen onze mensen goed. Hierdoor zorgen we voor een goede match tussen medewerker en opdracht.

  • Hoog kennisniveau

    Hoog kennisniveau

    Wij investeren in de kennis van onze experts met opleidingen, certificeringen en conferenties.

  • Flexibel

    Flexibel

    Wat de vraag of aanpassing ook is, wij schakelen snel en efficient.

  • Ondernemend

    Ondernemend

    Achterover leunen en afwachten is niet onze stijl. Onze experts denken graag proactief mee met de opdrachtgever.

  • Communicatief

    Communicatief

    Persoonlijk contact is ons kenmerk. Contact met de opdrachtgever en met de medewerkers staat centraal.

Onze opdrachtgevers

Onze architecten, beheerders, consultants, developers en engineers werken verspreid door het hele land bij opdrachtgevers in alle denkbare branches. Op zowel kortdurende als langdurende opdrachten. Wij werken niet alleen voor grote organisaties of A-merken, ook voor het MKB kunnen wij waardevolle experts inzetten om de bedrijfsprocessen te optimaliseren.

Zo ontstond er in het projectteam een goede combinatie tussen kennis van de organisatie, de processen én de techniek

Esra kwam aan het begin van onze samenwerking direct met goede adviezen en die zijn nu volledig doorgevoerd. David nam later het stokje van Esra over en heeft trainingen gegeven aan onze key users en medewerkers, ons begeleidt bij het inrichten van governance, en hij was onze vraagbaak. Ook heeft hij voor ons de samenwerkingsverbanden visueel weergegeven met Power BI. Zo ontstond er in het projectteam een goede combinatie tussen kennis van de organisatie, de processen én de techniek. Zowel met Esra als met David hebben we fijn samengewerkt, dat ging heel goed. Ze voelden dan ook echt als onderdeel van het projectteam.

Annemieke Stomps Projectmanager NTI

De developers van ShareValue hebben een goede werkhouding en zijn echte specialisten op hun vakgebied

De developers van ShareValue hebben een goede werkhouding en zijn echte specialisten op hun vakgebied. Ze hebben niet alleen de juiste papieren, maar houden ook hun vaardigheden bij. De één heeft meer ervaring dan de ander, maar ze begrijpen allemaal onze vraagstukken en leveren snel.

Ernst-Jan Heuseveldt Directeur Rovict

Ik ben erg blij met het team dat we hebben neergezet om de provincie Utrecht te begeleiden in het migratietraject en meer gebruik te maken van de Microsoft-mogelijkheden

De samenwerking met Esra gaat goed, ze is heel kundig. Ze doet hier van alles, van het implementeren van Teams tot het begeleiden en trainen van medewerkers. Straks komt ook Gerard ons versterken vanuit ShareValue. Omdat we meer willen halen uit de Microsoft-suite gaat hij ons helpen om de stip op de horizon te bepalen en wat er dan nodig is om daar te komen. Ik ben erg blij met het team dat we hebben neergezet om de provincie Utrecht te begeleiden in het migratietraject en meer gebruik te maken van de Microsoft-mogelijkheden.

Anika van Dam Projectleider implementatie Digitaal Samenwerken Provincie Utrecht

Bij ShareValue haal je altijd de juiste mensen in huis

Bij Carante Groep zoeken we altijd samenwerkingspartners, geen leveranciers. In ShareValue hebben we zo’n partner gevonden. Op het gebied van SharePoint, Nintex en projectleiding zetten we de deskundigen van ShareValue graag in. Je kunt erop vertrouwen dat je de juiste mensen in huis haalt om de afgesproken werkzaamheden uit te voeren.

Jerry van Rekom Hoofd ICT Carante Groep

De juiste keuze maken uit de vloed aan mogelijkheden

Sharevalue helpt ons al jaren de juiste keuze te maken uit de vloed aan mogelijkheden onder de paraplu van Office 365 en hoe we dit optimaal in onze organisatie kunnen inzetten. Zo werken we al jaren samen aan ons Intranet en Business apps op SharePoint en hebben in korte tijd ook OneDrive en Teams succesvol in gebruik genomen op onze kantoren in Europa.

Yakult

ShareValue heeft ons een uitstekende O365-professional geleverd

ShareValue heeft ons een uitstekende O365-professional geleverd. Met zijn hulp hebben we onze SharePoint omgeving kunnen moderniseren.

GGD-NOG

ShareValue vindt altijd de juiste man die matcht met de behoefte

Dbf en ShareValue kennen elkaar al vele jaren. ShareValue is in al die jaren altijd in staat geweest de juiste man te vinden die matcht met de behoefte van dbf op dat moment. Als het niet uit de eigen organisatie lukte, dan werd er verder gezocht in het brede netwerk wat ze inmiddels hebben.

Jasper Kruter directeur dbf

Altijd bereid om te helpen en mee te denken

Zeer fijne partner om mee samen te werken. Open en transparant naar ons toe en altijd bereid om te helpen en mee te denken!

Een grote pensioenorganisatie

Wat speelt er bij ShareValue?

Joost Joost / 24-08-2023

2 minuten lezen

Wanneer je als grote organisatie met oplossingen werkt binnen het Power Platform, is het raadzaam om een Application Lifecycle Management (ALM) te implementeren. Hiermee kan je de aanpassingen die je wil maken op de in productie draaiende oplossingen op een veilige en gebruiksvriendelijke manier implementeren. 


Met de nieuwste update van deze maand wordt er door middel van AI een omschrijving gemaakt van jouw gemaakte aanpassingen in de nieuwe oplossing-versie die je wilt implementeren. Hoe dat werkt? Leg ik je verder uit in deze blog.

ALM

Wat is Application Lifecycle Management (ALM)?

Voordat we deze update verder beschrijven, wil ik je wijzen op de documentatie van Microsoft over ALM. Hierin wordt stap voor stap uitgelegd wat het betekent en hoe je het kan implementeren binnen jouw omgeving.

Oplossingen

Wat zijn oplossingen?

Oplossingen zijn het mechanisme voor het implementeren van ALM in Power Apps en Power Automate.

Wanneer je met oplossingen werkt, kunnen deze snel erg complex worden en bevatten ze vaak tientallen componenten die moeilijk te scheiden en samen te vatten zijn. Wanneer je deze oplossingen i.c.m. pijplijnimplementaties (ALM) gaat implementeren op de gewenste omgevingen (Test, Productie), moeten beheerders de oplossingen zelf eerst openen om inzicht te krijgen wat er precies is veranderd ten opzichte van de vorige versie.

Door makers tijdens de implementatie van de oplossing te helpen bij het automatisch genereren van een nuttige oplossingsbeschrijving met AI, voorkom je onnodig werk van een beheerder. 

Hoe werkt het?

Hoe werkt het?

  1. Meld je aan bij de Power Platform-omgeving waar de oplossing staat. (make.powerapps.com).
  2. Nu gaan we naar de tab Oplossingen en selecteren we een onbeheerde oplossing om te implementeren.
  3. We kiezen nu voor: Selecteer Pijpleidingen in het linker navigatievenster, en vervolgens Implementeren op de opdrachtbalk.
  4. Kies de fase waarin je de oplossing wilt implementeren, en selecteer Hier implementeren.
  5. Kies Nu implementeren of plannen voor Later en selecteer vervolgens Volgende in het rechterdeelvenster.
     

 

Bij de laatste stap op de overzichtspagina van de implementatie, zie je de door AI gegenereerde oplossingsoverzicht. Deze wijzigingen zijn nog aan te passen. Pas als je op Toepassen drukt, worden de wijzigingen opgeslagen in de oplossingen.

Conclusie

Met pijplijnimplementaties (ALM) neem je al veel werk uit handen. Nu met deze aanpassing wordt het implementeren steeds makkelijker, veiliger en gebruiksvriendelijker. Het ziet er naar uit dat AI een steeds grotere rol gaat krijgen binnen het Power Platform. Ik ben erg benieuwd wat de volgende aanpassing gaat worden.

Meer weten?

Wil je meer weten over deze functionaliteit? Neem dan gerust contact met ons op, zodat we de mogelijkheden kunnen bespreken.

Joost Joost / 29-06-2023

3 minuten lezen

Dat je beveiligingsrollen kunt gebruiken is niet nieuw, de manier hoe je deze inzet gaat wel veranderen. Deze maand zal je enkele wijzigingen tegenkomen in de manier waarop beveiligingsrollen worden geopend vanuit het Power Platform beheercentrum.

Wanneer je, als maker, een App of Flow ontwikkelt, zie je niet direct wat er op de achtergrond ingeregeld wordt om jouw creatie binnen de gestelde kaders van het bedrijf veilig te kunnen inzetten.

Deze instellingen worden vaak door een beheerder aangescherpt binnen het Power Platform beheercenter. Een van deze instellingen die beheerders kunnen inzetten zijn beveiligingsrollen (security roles). Met deze beveiligingsrollen geef je gebruikers de juiste rechten op de verschillende omgevingen. Deze manier van rechten geven gaat veranderen.
 

De nieuwe indeling

Laten we eens kijken naar de nieuwe functionele indeling voor beveiligingsrollen in het Power Platform-beheercentrum. Om toegang te krijgen tot de beveiligingsrollen, openen we eerst het Power Platform beheercentrum (admin center), daarna selecteer je de omgeving waarop je dit wilt toepassen. Vervolgens open je de instellingen en selecteer je de beveiligingsrollen.

 

Zodra je op de beveiligingsrollen klikt, word je naar de lijst met beveiligingsrollen genavigeerd. Hier is de eerste wijziging al meteen zichtbaar.

Een schakelaar boven in je scherm die standaard is ingeschakeld. Deze laat alleen de bovenliggende beveiligingsrollen (rootniveau) zien.

Wanneer je op de drie stippen (...) naast een bepaalde beveiligingsrol klikt, krijg je de mogelijkheid om een rol te bewerken. Wanneer we op de knop bewerken klikken, zien we een nieuw scherm met de beveiligingsroleditor. 

Bovenaan het scherm hebben we de optie van de privilege-erfenis voor de leden van groep. 

(1) Hier selecteer je het toegangsniveau voor directe gebruikers en teamniveau of alleen teamniveau. Rechtsonder zie je drie tabbladen voor de soorten rechten die je wil wijzigen zoals: tabellen, diversen of privacy gerelateerd.

Onderaan dit tabblad is er een vervolgkeuzelijst met 3 opties waarmee je: alleen toegewezen tabellen / bevoegdheden of alle toegewezen tabellen / bevoegdheden of niet-toegewezen tabellen / bevoegdheden kan weergeven. 

(2) Met deze keuzelijst hoef je niet meer naar een bepaalde rol te zoeken als je de rechten wilt wijzigen. Je kan ervoor kiezen om alleen de rechten te laten zien die in gebruik zijn. Of als het nodig is om nieuwe rechten in te stellen, selecteer je het niet-toegewezen overzicht.
 

 

Zodra je het type bevoegdheden hebt geselecteerd dat je wil wijzigen: Tabellen, Diversen of Privacy, zie je meteen de lijst met bevoegdheden en kan je een rij selecteren om de bevoegdheden te wijzigen. 

Elke rij toont een vervolgkeuzelijst waarin je de bevoegdheid naar keuze kunt wijzigen.

 

Je kan hetzelfde doen voor diverse en privacy privileges. Je zult merken dat privacy privileges bovenaan een banner heeft die aangeeft dat elk van deze privileges het mogelijk maakt om de gegevens buiten de dataverse-omgeving te verwijderen, zoals exporteren naar Excel, synchroniseren met Outlook of afdruk samenvoegen.

 

Met behulp van de oude portal hadden we de mogelijkheid om de bevoegdheden voor de hele rij te wijzigen. Die functionaliteit is veranderd in de nieuwe interface. Wanneer je een rij selecteert, en klikt op de opties Meer (...), selecteer dan machtigingsinstellingen. Nu kan je de machtigingen vanuit een vooraf gedefinieerde lijst kiezen zoals: Geen toegang, Volledige toegang, Samenwerken, Privé, Referentie of Aangepast. 

Conclusie

Met de komst van dit nieuwe uiterlijk en manier van beveiligingenrollen toekennen, geef je de Power Platform beheerders de mogelijkheid om efficiëntie en makkelijker beveiligingsrollen in te stellen voor de hele organisatie of alleen op persoons niveau. Kortom; een wijziging die erg welkom is en een positieve impact gaat geven in het beheer van Het Power Platform.

 

Wil je meer weten over deze functionaliteit of over het Power Platform in het algemeen? Neem dan gerust contact op met ons zodat we de mogelijkheden kunnen bespreken. 

Marco Marco / 22-06-2023

12 minuten lezen

Het internet staat tegenwoordig vol met Pixel Displays zoals de Divoom Pixoo-64 of misschien wel de bekendste, de LaMetric clock. Maar de prijzen van deze displays schrokken mij nogal af. Toen kwam ik op Amazon de Coolwell RGB Full-Color LED Matrix Panel tegen. 

Toevallig had mijn collega Raymon hetzelfde scherm gevonden en al in bezit. Hij kon mij precies vertellen wat er allemaal bij zat en wat er nog moest worden aangeschaft. Met maar 40 euro is dit een veel schappelijkere prijs. Echter kan het scherm zelf niet meer dan hem verteld wordt, dus is er een controller nodig. Iets wat het scherm vertelt “dit moet je tonen”. 

De Raspberry Pi zou hier zeer geschikt voor zijn, klein maar krachtig genoeg om een API te draaien en het scherm aan te sturen. Zo is dit project dus begonnen.

In deze blog leg ik de volgende dingen uit:

  • Hoe de kabel mapping in elkaar steekt
  • Hoe het scherm opdrachten krijgt vanuit .NET
  • Hoe je graphics omzet naar bitmaps en vervolgens naar pixels zodat het scherm dit begrijpt

Kabel mapping

Kabel mapping

Om het scherm aan te sturen, moet deze worden aangesloten op de Raspberry Pi. De pins van het scherm moeten op de juiste pins van de GPIO header van de Raspberry Pi worden aangesloten zodat de Raspberry Pi de commando’s kan geven om op het scherm te tekenen.

GPIO header pins

GPIO header pins

De GPIO (General Purpose Input/Output) header pins op een Raspberry Pi zijn fysieke aansluitpunten op het bord die verschillende functies bieden voor het verbinden van externe apparaten.

Voor meer informatie over de functionaliteit van alle pins verwijs ik door naar: https://pinout.xyz/pinout/pin3_gpio2 en https://www.raspberrypi-spy.co.uk/2012/06/simple-guide-to-the-rpi-gpio-header-and-pins/
 

Pixel display pins

Pixel display pins

Het pixel display heeft de volgende pins op de achterkant:

  • R1: Deze pin wordt gebruikt om de intensiteit van de rode kleur van de LED's in het display te regelen.
  • G1: Deze pin wordt gebruikt om de intensiteit van de groene kleur van de LED's in het display te regelen.
  • B1: Deze pin wordt gebruikt om de intensiteit van de blauwe kleur van de LED's in het display te regelen.
  • R2: Deze pin wordt gebruikt voor extra controle van de rode kleurintensiteit in displays die ondersteuning bieden voor dubbele kleurkanalen.
  • G2: Deze pin wordt gebruikt voor extra controle van de groene kleurintensiteit in displays die ondersteuning bieden voor dubbele kleurkanalen.
  • B2: Deze pin wordt gebruikt voor extra controle van de blauwe kleurintensiteit in displays die ondersteuning bieden voor dubbele kleurkanalen.
  • A, B, C, D: Deze pinnen worden gebruikt voor het selecteren van de rij- of kolomadressen van het display, waardoor specifieke rijen of kolommen van LED's kunnen worden ingeschakeld of uitgeschakeld.
  • CLK: Deze pin wordt gebruikt voor klok-synchronisatie en timingcontrole van gegevensoverdracht naar het display.
  • LAT: Deze pin wordt gebruikt om de gegevens in de shiftregisters van het display vast te leggen, waardoor de weergegeven afbeelding wordt bijgewerkt.
  • OE: Deze pin wordt gebruikt om de uitvoer van het display in of uit te schakelen.
  • GND: Deze pin is de grondaansluiting voor het displaymodule.
  • E: Deze pin komt overeen met de extra rij (E-rij) en wordt gebruikt voor specifieke functies of adresseringsdoeleinden.
     

Mapping

Mapping

De pins die gebruikt worden voor het aansturen van het pixel display zijn:

  • Pin 6 ( GND ), deze pin wordt verbonden aan de eerste GND van het display
  • Pin 7 (GPIO4 ). Dit is een algemene klokpuls uitgang. Het kan worden gebruikt om klokpulsen te genereren voor verschillende toepassingen. Deze gaat op de LAT pin van het display
  • Pin 9 ( GND ), deze pin wordt verbonden aan de tweede GND van het display
  • Pin 10 ( GPIO15/RXD0 ). Dit is een UART RX (ontvangst) pin. Het wordt gebruikt voor het ontvangen van seriële communicatie. Gaat op de E pin van het display
  • Pin 11 ( GPIO17 ). Deze wordt verbonden met de N pin van het display *
  • Pin 12 ( GPIO18 ). Deze wordt verbonden met de OE pin van het pixel display
  • Pin 13 ( GPIO27 ) . Deze wordt verbonden met de G1 pin van het pixel display *
  • Pin 15 ( GPIO22 ). Deze wordt verbonden met de A pin van het pixel display *
  • Pin 16 ( GPIO23 ). Deze wordt verbonden met de B pin van het pixel display *
  • Pin 18 ( GPIO24 ) . Deze wordt verbonden met de C pin van het pixel display *
  • Pin 19 ( MOSI/GPIO10 ). Dit is een SPI (Serial Peripheral Interface) Master Output Slave Input-pin. Het wordt gebruikt voor seriële communicatie met SPI-apparaten. Gaat op B2 van het pixel display
  • Pin 21 ( MISO/GPIO9 ). Dit is een SPI Master Input Slave Output-pin. Het wordt gebruikt voor seriële communicatie met SPI-apparaten. G2 van het pixel display.
  • Pin 22 ( GPIO25 ) *
  • Pin 23 ( SCLK/GPIO11 ). Dit is een SPI-klokpin. Het wordt gebruikt voor het synchroniseren van gegevensuitwisseling met SPI-apparaten. R1 van het pixel display
  • Pin 24 ( CE0/GPIO8 ). Dit is een SPI Chip Select 0-pin. Het wordt gebruikt om te selecteren welk SPI-apparaat met de Raspberry Pi communiceert. R2 van het pixel display
  • Pin 26 ( CE1/GPIO17 ). Dit is een SPI Chip Select 1-pin. Het wordt gebruikt om een ander SPI-apparaat te selecteren voor communicatie met de Raspberry Pi. B1 van het pixel display

* Dit is een algemene GPIO-pin
 

Scherm

Aansturen van het scherm

Om het scherm aan te sturen heb ik gebruik gemaakt van een open-source library, ontwikkeld door Henner Zeller, voor het aansturen van RGB LED-matrixpanelen met de Raspberry Pi: https://github.com/hzeller/rpi-rgb-led-matrix

 

Deze library stelt je in staat om RGB LED-matrixpanelen aan te sluiten op je Raspberry Pi en ze te bedienen via de GPIO-pinnen. Het biedt geavanceerde functionaliteiten voor het weergeven van kleurrijke patronen, afbeeldingen en animaties op de LED-matrix.

Om deze library te kunnen gebruiken in een .NET project, moet er een dll van gemaakt worden. Gelukkig heeft Henner hier aan gedacht en hier een handleiding voor geschreven: https://github.com/hzeller/rpi-rgb-led-matrix/tree/master/bindings/c%23

Mapping testen

Testen mapping

Voordat er code geschreven kan worden moet er eerst getest worden of het scherm goed werk en/of de kabels goed zijn aangesloten op de Raspberry Pi. De eerder genoemde library heeft een aantal scripts om bijvoorbeeld tekst op het scherm te printen, een plaatje te tonen of scrolling tekst.

Door deze scripts aan te roepen kon ik zien of de kabels goed zaten. Zo zaten er bij de eerste keer de B en D kabels omgedraaid, wat er in resulteerde dat de onderste helft van het plaatje boven getoond werd en andersom.  Als alle scripts de juiste output tonen is het tijd om verder te gaan naar het schrijven van C# API.
 

.NET

.NET

Als de kabels goed zitten en de dll gemaakt is, kunnen we het .NET project opzetten. Ik heb gekozen voor een API, omdat ik het vanaf het netwerk of misschien zelfs vanaf het internet aan wil kunnen roepen. Maar uiteraard kan er ook een console application gemaakt worden om het scherm aan te sturen, dit ligt eraan wat de wensen zijn.

API

API

Nu de keuze duidelijk is kan ik eindelijk code gaan schrijven. Natuurlijk met de nieuwste .NET versie, en dat is op het moment van schrijven .NET 7. 
De API moet een REST API zijn en vooralsnog zonder authenticatie, want eerst moet getest worden of alles werkt. De authenticatie is alleen echt nodig als het scherm echt wordt opgehangen voor gebruik, en zelfs dan kan het zelfs niet nodig zijn. Natuurlijk als het scherm aan het internet gehangen wordt, dan moet er wel authenticatie ingebouwd worden.

Plaatjes

Plaatjes

De REST API endpoint maken was het makkelijke werk, maar hoe zet je een plaatje om naar pixels? Het scherm bestaat immers uit pixels. Dit heb ik gedaan met de volgend code:
 

 

public void DrawBitmapFromUrl(string imageUrl)
    {
        var bitmap = GraphicsHelper.GetBitmapFromUrl(imageUrl, _ledRows, _ledColumns).Result;

        var canvas = Matrix.CreateOffscreenCanvas();
        canvas = DrawBitmapOnCanvas(canvas, bitmap);

        SwapCanvas(canvas);
    }


 

Het endpoint roept DrawBitmapFromUrl aan, deze vraagt aan de GraphicsHelper om de bitmap op te halen. Vervolgens wordt er een canvas aangemaakt om op te tekenen, de bitmap wordt daarop getekend en het canvas wordt verwisseld met de huidige canvas die op het scherm getoond wordt. Het wisselen van de canvas is het daadwerkelijke tekenen op het scherm.

 

public static async Task<SKBitmap> GetBitmapFromUrl(string url, int screenWidth, int screenHeight)
    {
        using var client = new HttpClient();
        using var response = await client.GetAsync(url);
        using var stream = await response.Content.ReadAsStreamAsync();

        var bitmap = SKBitmap.Decode(stream);

        return ResizeBitmap(screenWidth, screenHeight, bitmap);
    }  


 

De GetBitmapFromUrl methode download het plaatje en zet het om naar een stream. De stream kan gedecode worden naar een SKBitmap. Deze wordt vervolgens aan de ResizeBitmap method gegeven met de hoogte en breedte van het scherm.

SKBitmap is onderdeel van de SkiaSharp Nuget package: https://www.nuget.org/packages/SkiaSharp/

 

 

private static SKBitmap ResizeBitmap(int screenWidth, int screenHeight, SKBitmap bitmap)
    {
        int targetWidth, targetHeight;
        CalculateDimensions(bitmap, screenWidth, screenHeight, out targetWidth, out targetHeight);

        // Create a new bitmap with the desired dimensions
        var resizedBitmap = new SKBitmap(targetWidth, targetHeight);

        // Create a new surface from the resized bitmap
        using (var surface = new SKCanvas(resizedBitmap))
        {
            // Draw the original bitmap onto the new surface, scaling it to fit while maintaining aspect ratio
            surface.DrawBitmap(bitmap, SKRect.Create(targetWidth, targetHeight));
        }

        return resizedBitmap;
    }


 

De ResizeBitmap method berekend de hoogte en breedte aan de hand van de dimensies van het scherm met behoud van de aspect ratio. Vervolgens wordt er een SKCanvas geïnitialiseerd met de juiste dimensies en daar wordt de bitmap op getekend.

Gifjes

Gifjes

Gifjes tekenen op het scherm gaat bijna hetzelfde als een plaatje. Alleen een gifje is niet een stilstaand plaatje. Een gif bestaat uit meerdere plaatjes die een bepaalde periode getoond worden.

 


private RGBLedCanvas DrawGifOnCanvas(RGBLedCanvas canvas, string imageUrl, RenderPoint start, RenderPoint end, CancellationToken cancellationToken)
    {
        (List<SKBitmap> frames, List<int> durations) = GraphicsHelper.IsBase64String(imageUrl) ? GraphicsHelper.GetGifFromBase64(imageUrl, end.Y - start.Y, end.X - start.X)  : GraphicsHelper.GetGifFromUrl(imageUrl, end.Y - start.Y, end.X - start.X);

        while(!cancellationToken.IsCancellationRequested)
        {
            for(var i = 0; i < frames.Count; i++)
            {
                canvas = DrawBitmapOnCanvas(canvas, frames[i], start, end);
                canvas = SwapCanvas(canvas);

                Thread.Sleep(durations[i]);
            }
        }

        return canvas;
    }


 

De DrawGifOnCanvas methode vraag aan de GraphicsHelper om de gif op te halen en krijgt een tuple van frames en durations terug. Door deze tuple wordt heen gelopen, de bitmap wordt op het scherm getekend en vervolgens wordt er gewacht ( de duration van de bitmap ).

 

public static (List<SKBitmap> frames, List<int> durations) GetGifFromUrl(string url, int screenWidth, int screenHeight)
    {
        using var client = new HttpClient();
        using var stream = client.GetAsync(url).Result.Content.ReadAsStream();

        return GetGifFromStream(screenWidth, screenHeight, stream);
    }


 

Deze methode download het gifje, geeft deze aan GetGifFromStream mee en geeft het resultaat terug.

 

private static (List<SKBitmap> frames, List<int> durations) GetGifFromStream(int screenWidth, int screenHeight, Stream response)
    {
        using (var codec = SKCodec.Create(response))
        {
            var frameCount = codec.FrameCount;
            Console.WriteLine($"Frame count: {codec.FrameCount}");

            var info = codec.Info;
            var count = codec.FrameCount;

            // Get all frames from gif and duration and add to list
            var bitmap = new SKBitmap(info);
            var frames = new List<SKBitmap>();
            var frameLengths = new List<int>();

            for (int i = 0; i < count; i++)
            {
                var opts = new SKCodecOptions(i);

                if (codec?.GetPixels(info, bitmap.GetPixels(), opts) == SKCodecResult.Success)
                {
                    bitmap.NotifyPixelsChanged();

                    var resized = ResizeBitmap(screenWidth, screenHeight, bitmap);

                    frames.Add(resized);
                    frameLengths.Add(codec.FrameInfo[i].Duration);
                }
            }

            return (frames, frameLengths);
        }
    }


 

GetGifFromStream maakt een SKCodec (SkiaSharp) en loopt door de frames. Van elk frame wordt de bitmap opgehaald (geresized naar de juiste dimensies) en de duration.

Tekst

Tekst

Om tekst te tonen op het scherm roept de endpoint DrawText aan.

 

public void DrawText(string text, CancellationToken cancellationToken)
    {
        text = text ?? "This is a static text.";

        var canvas = Matrix.CreateOffscreenCanvas();

        canvas = DrawTextOnCanvas(canvas, text, new RenderPoint(1, 6), null);

        SwapCanvas(canvas);
    }

 

De canvas is aangemaakt om op te tekenen en DrawTextOnCanvas wordt aangeroepen. Vervolgens wordt er weer de SwapCanvas methode aangeroepen om de tekst op het scherm te tekenen.

 

private RGBLedCanvas DrawTextOnCanvas(RGBLedCanvas canvas, string text, RenderPoint start, RenderPoint? end)
    {
        var font = new RGBLedFont("fonts/6x10.bdf");

        var textLength = canvas.DrawText(font, start.X, start.Y, new Color(0, 255, 0), text);

        // TODO make text as big as fits in the section
        canvas.DrawText(font, start.X, start.Y, new Color(0, 255, 0), text);

        return canvas;
    }

 

Het font wordt geladen, de tekst wordt op de canvas getekend en de canvas wordt terug gegeven.

De DrawText is een methode uit de dll die gecompileerd is uit de eerder genoemde library van Henner Zeller.

Scrolling tekst

Scrolling tekst

Scrolling tekst werkt hetzelfde als de gewone tekst, alleen de tekst beweegt (scrolt) over het scherm.

 

public void ScrollText(string text, CancellationToken cancellationToken)
    {
        text = text ?? "This is a scrolling text.";

        var canvas = Matrix.CreateOffscreenCanvas();
        var font = new RGBLedFont("fonts/6x10.bdf");

        var textLength = canvas.DrawText(font, 1, 6, new Color(0, 255, 0), text);

        canvas = Matrix.CreateOffscreenCanvas();

        int animationCount = 0;

        while (animationCount < 5 && !cancellationToken.IsCancellationRequested)
        {
            var x = canvas.Width;
            canvas.Clear();

            while (x > -textLength) {
                canvas.DrawText(font, x, 20, new Color(0, 255, 0), text);
                x -= 1;
                canvas = SwapCanvas(canvas);

                Thread.Sleep(50);
            }

            animationCount++;
            x = canvas.Width;
        }
    }


 

De canvas wordt aangemaakt, het font geladen en de lengte van de tekst bepaald door te tekenen op de canvas. 

De tekst wordt 5 keer gescrold door het scherm, en bij elke animatie wordt de tekst telkens opnieuw getekend op het scherm maar dan 1 pixel naar links. Dit geeft de illusie van een bewegende tekst: het scrollen. 

Issues

Waar liep ik tegen aan?

Toen ik eenmaal wat ideeën had uitgeschreven in code was het tijd om te testen of het werkt. Ik kreeg netjes het plaatje te zien op het scherm, of de tekst. Zelfs gifjes werkten, maar meerdere commando’s achter elkaar leken niet te werken. De applicatie bleef hangen. 

In de logging stond een foutmelding dat de applicatie niet de juiste rechten had bij een volgend commando. Multi-threading was een issue hier. Er moest één verbinding komen met het scherm en niet elke keer een nieuwe. Gelukkig is hier een simpel pattern voor, de singleton. Dit loste de problemen op en achtereen volgende commando’s werden goed verwerkt.
 

GitHub

GitHub

De uiteindelijke API, met wat uitleg over de endpoints is te vinden op GitHub: https://github.com/marcokreeft87/pixel-sharp
 

Werkend scherm

We helpen graag!

Wil jij ook iets als dit laten werken met .NET en kan je daar hulp bij gebruiken? Mijn collega’s en ik helpen graag!

{description}

Heb je een Microsoft Expert nodig?

Neem contact met ons op
{description}

Zoek je een nieuwe baan?

Bekijk onze vacatures