[GELÖST]Automatische Bildkonvertierung

15. Februar 2013 10:16

Hallo zusammen :-)

ich bin seit ein paar Tagen dabei mich mit Dynamics NAV 2013 auseinander zu setzen.
Nun wollte ich gerne Bilder automatisiert in eine bestimmte Größe konvertieren und als Datei abspeichern lassen - der Code aus älteren NAV Versionen (z.B. auch 2009 R2) funktioniert nicht mehr (BLOBExport).

Nach langem hin und her habe ich eine Lösung gefunden, welche super funktioniert, sofern ich die Codeunit selbst aufrufe. Ich möchte den Prozess allerdings gerne im Hintergrund in der "Job Queue" laufen lassen und dort bekomme ich dann folgende Warnung im Ereignisprotokoll und die Funktion wird auch nicht ausgeführt - der Log-Eintrag vom Job Queue sagt allerdings Status "Success":
Microsoft Dynamics NAV Server attempted to issue a client callback to download a file: (CodeUnit XXXX XXXX). Client callbacks are not supported on MIcrsoft Dynamics NAV Server.

Ist es auch irgendwie möglich, dass ich das Dateiformat des Bildes, welches als BLOB gespeichert ist, rausfinde? Also jpg, gif, png, bmp, uvm...

Hier mal ein Auszug aus dem Code:
Bitte lasst euch wegen "Images" nicht verwirren, das ist eine eigene Tabelle.
"convertBinary" ist eine Text Konstante zum Pfad für die convert.exe von ImageMagick.
Code:
    newFilename := 'test_image'
    ConvSuccess := FALSE;

    Images.CALCFIELDS(Picture);
    IF Images.Picture.HASVALUE THEN BEGIN
      Images.Picture.CREATEINSTREAM(NewInStream);
      ReturnImgValue := DOWNLOADFROMSTREAM(NewInStream, '', '<TEMP>', '', MagicPath);

      IF ReturnImgValue THEN BEGIN
        CREATE(WSH, FALSE, TRUE);
        TempFileOut := WSH.ExpandEnvironmentStrings('%TEMP%')+'\'+newFilename+'.jpg';
        TempFileIn := MagicPath;

        WSH.Run(convertBinary + ' -geometry 1024x768 -quality 90 "'+TempFileIn+'" "'+TempFileOut+'"');

        ConvSuccess := TRUE;
        CLEAR(WSH);
      END;
    END;


Hat irgendjemand dasselbe Problem oder weiß jemand eine Lösung? Ich bin für jeden Tip dankbar...
Zuletzt geändert von seitz am 19. Februar 2013 13:02, insgesamt 1-mal geändert.

Re: Automatische Bildkonvertierung

15. Februar 2013 10:44

Hi,

schau dir doch einmal folgende Alternative an. Vielleicht ist die eher etwas für die arbeit auf dem ServiceTier.
viewtopic.php?f=17&t=13226&hilit=.net+bild

Re: Automatische Bildkonvertierung

15. Februar 2013 10:48

Den gleichen Link hätte ich nun auch geschrieben :-P

Kann ich nur empfehlen. Läuft wie geschnitten Brot und durch kleine Änderungen werden alle Fehler erkannt und zurückgegeben (z.B. bei Verarbeitung eines "Nicht-Bildes").

Re: Automatische Bildkonvertierung

15. Februar 2013 11:07

Danke für die schnellen Antworten :-)
Ich kann kein C# aber ist das nicht falsch rum?
-> Datei auslesen, in BMP konvertieren in BLOB speichern

und ich müsste
-> BLOB auslesen, zu JPG konvertieren und unter Pfad C:\Pfad\zur\Datei\ ablegen

Haltet mich jetzt nicht für doof aber wie bekomme ich C# Code in NAV zum Laufen? Was muss ich da machen?
Ich versuchs mal, vielleicht funktionierts :-)

Re: Automatische Bildkonvertierung

15. Februar 2013 15:27

seitz hat geschrieben:Ich kann kein C# aber ist das nicht falsch rum?
-> Datei auslesen, in BMP konvertieren in BLOB speichern

und ich müsste
-> BLOB auslesen, zu JPG konvertieren und unter Pfad C:\Pfad\zur\Datei\ ablegen


Ja, der Weg in dem Beispiel geht den anderen Weg. Ich denke aber, dass der Aufwand nicht so erheblich ist, das auch in die andere Richtung durchzuführen ;)

seitz hat geschrieben:Haltet mich jetzt nicht für doof aber wie bekomme ich C# Code in NAV zum Laufen? Was muss ich da machen?
Ich versuchs mal, vielleicht funktionierts :-)


Pidi hat leider auch keine kompilierte DLL angebunden. Du müsstest also selber dafür sorgen, dass du den Quellcode (du musst natürlich den anderen Weg gehen) kompilierst (es gibt Anleitungen zur Erstellung von DLLs für Navision). Danach musst du (evtl. die DLL vorher registrieren) in Navision als Automation anbinden.

Zugegeben, es ist jetzt als kompletter Anfänger vielleicht nicht das leichteste Unterfangen. Probiers mal und wenn du es nicht hinbekommst, dann schau ich es mir vielleicht mal an.

Re: Automatische Bildkonvertierung

15. Februar 2013 15:48

Vielleicht lässt sich das alles auch mit .NET (=DotNet-Variablen in NAV) abbilden, ohne den Umweg über eine DLL? Streamen geht in jedem Fall, bei der Konvertierung bin ich überfragt.

Re: Automatische Bildkonvertierung

19. Februar 2013 11:45

Also ich habe es jetzt endlich mal soweit geschafft, dass ich in C# was geschrieben habe, was ich in NAV aufrufen kann :-)
Allerdings bekomme ich folgende Fehlermeldung: "Client callbacks are not supported on Microsoft Dynamics NAV Server"

Das hier wäre mein Aufruf in NAV:
Code:
      Images.Picture.CREATEINSTREAM(newinstream);
      CREATE(ConvertStreamToJpg, FALSE, TRUE);
      ConvertStreamToJpg.ConvertStreamToJpeg(newinstream, 'C:\TEST\test.jpg', 200, 200);


Und so guckt der C# Code aus:
Code:
public void ConvertStreamToJpeg(object ObjPictureStream, string StrTargetFile, int NewHeight, int NewWidth)
        {
            Size MySize = new Size(NewWidth, NewHeight);
            Image MyImage = Image.FromStream(ObjPictureStream as Stream);
            Bitmap MyJpeg = new Bitmap(MyImage, MySize);
            MyJpeg.Save(StrTargetFile);
            MyImage.Dispose();
            MyJpeg.Dispose();
        }


Ein weiterer Versuch war diese Funktion:
Code:
public void ConvertStreamToBmp(object ObjPictureStream, string StrTargetFile, int NewHeight, int NewWidth)
        {
            Stream StmPicStream = ObjPictureStream as Stream;

            Image img = Image.FromStream(StmPicStream);
            Size MySize = new Size(NewWidth, NewHeight);
            Bitmap MyBitMap = new Bitmap(img, MySize);
            MyBitMap.Save(StrTargetFile, ImageFormat.Jpeg);

            img.Dispose();
            MyBitMap.Dispose();
        }


Habt ihr vielleicht noch weitere Tipps, Ratschläge, Lösungen, usw.? Ich verzweifel hier schön langsam... :-(

Re: Automatische Bildkonvertierung

19. Februar 2013 12:59

HI,

http://www.codeproject.com/Articles/2122/Image-Processing-for-Dummies-with-C-and-GDI-Part-4 um die Bildgröße anzupassen.

Das ganze in eine Website gepackt. In der Website einen Webservice erstellt, der eine Funktion bool ShrinkAndSave(Bitmap bmp, string Saveto) zur Verfügung stellt. Dann Datei aus Blob exportieren und der o. g. Funktion übergeben.

Volker

Re: Automatische Bildkonvertierung

19. Februar 2013 13:00

Jetz hab ichs!!!! :-)

Das Problem war, dass auf dem Microsoft Dynamics NAV Server keine Automation Objekte mehr erstellt werden können - die registrierte DLL kann aber auch über den Variablen-Typ "DotNet" benutzt werden.
Das Bild wird jetzt über die Job Queue in die entsprechenden Maße (in meinem Beispiel 200 x 200) konvertiert und unter dem entsprechenden Pfad abgespeichert.

Sollte es irgendwann irgendjemanden helfen - hier die Lösung:

NAV:
Die Variable "ConvStreamToFile" ist vom Typ "DotNet".
Code:
Images.CALCFIELDS(Picture);
IF Images.Picture.HASVALUE THEN BEGIN
    Images.Picture.CREATEOUTSTREAM(NewOutStream);
    ConvStreamToFile := ConvStreamToFile.ConvertStreamToJpg();
    ConvStreamToFile.ConvertStreamToJpeg(NewOutStream, 'C:\test\test.jpg', 200, 200);
END;



C#:
Code:
public void ConvertStreamToJpeg(object ObjPictureStream, string StrTargetFile, int NewHeight, int NewWidth)
        {
            Size MySize = new Size(NewWidth, NewHeight);
            Image MyImage = Image.FromStream(ObjPictureStream as Stream);
            Bitmap MyJpeg = new Bitmap(MyImage, MySize);
            MyJpeg.Save(StrTargetFile);
            MyImage.Dispose();
            MyJpeg.Dispose();
        }

Re: [GELÖST]Automatische Bildkonvertierung

19. Februar 2013 13:14

Nur eine kurze Anmerkung. Dein Code berücksichtigt nicht das Seitverhältnis des originalen Bildes. Dein verkleinertes Bild kann dann verzerrt sein.

Volker

Re: [GELÖST]Automatische Bildkonvertierung

19. Februar 2013 13:14

Nur eine kurze Anmerkung. Dein Code berücksichtigt nicht das Seitverhältnis des originalen Bildes. Dein verkleinertes Bild kann dann verzerrt sein.

Volker

Re: [GELÖST]Automatische Bildkonvertierung

19. Februar 2013 14:16

vsnase hat geschrieben:Nur eine kurze Anmerkung. Dein Code berücksichtigt nicht das Seitverhältnis des originalen Bildes. Dein verkleinertes Bild kann dann verzerrt sein.

Volker


So ist es! Du kannst alternativ überall die Größenangaben rausnehmen, dann wird die Größe 1:1 übernommen (natürlich ist es dann auch nicht möglich zu verkleinern/vergrößern).

Code:
public void ConvertStreamToJpeg(object ObjPictureStream, string StrTargetFile)
        {
            Image MyImage = Image.FromStream(ObjPictureStream as Stream);
            Bitmap MyJpeg = new Bitmap(MyImage);
            MyJpeg.Save(StrTargetFile);
            MyImage.Dispose();
            MyJpeg.Dispose();
        }

Re: [GELÖST]Automatische Bildkonvertierung

19. Februar 2013 14:22

Stimmt, danke!
Habe ich gerade noch eingebaut :-) Jetzt werden die Seitenverhältnisse berechnet und die Parameter sind die Höchstmaße.

Code:
public void ConvertStreamToJpeg(object objPictureStream, string strTargetFile, int height, int width, bool preserveAspectRatio = true)
        {
            Image myImage = Image.FromStream(objPictureStream as Stream);

            if (preserveAspectRatio)
            {
                int origWidth = myImage.Width;
                int origHeight = myImage.Height;
                float percWidth = (float)width / (float)origWidth;
                float percHeight = (float)height / (float)origHeight;
                float percent = percHeight < percWidth ? percHeight : percWidth;
                width = (int)(origWidth * percent);
                height = (int)(origHeight * percent);
            }
            Size mySize = new Size(width, height);
            Bitmap myJpeg = new Bitmap(myImage, mySize);

            myJpeg.Save(strTargetFile);
            myImage.Dispose();
            myJpeg.Dispose();
        }