2012-03-30 24 views
4

Ich benutze eine Funktion, die ein Bild hochlädt, den Stream nimmt und die Größe mit imaginesizer.net ändert, und dann den Stream auf Amazon S3 hochlädt.Bild in Stream konvertieren

Jetzt möchte ich ein lokales Bild machen und es in einen Stream umwandeln. (um die Größe zu ändern und zu amazonS3 hochzuladen). Wie konvertiert man ein Bild in einen Stream?

Dies könnte eine einfache Frage sein, konnte einfach nicht die Antwort irgendwo finden.

Hier ist ein grundlegender Code.

Public Shared Sub MoveToAmazon(strImg As String, SKU As String) 
     Dim fullImg As String = "C:\ImageLocation\" & strImg 
     Dim img As Image = Image.FromFile(fullImg) 

     'Here Im missing the code to convert it to a stream. 
     UploadImage(imgStream, SKU) 

End Sub 


Public Shared Sub UploadImage(imgStream As Stream, imgName As String) 

    Dim MainStream As Stream = New MemoryStream 
    Dim HomeStream As Stream = New MemoryStream 
    Dim SmallStream As Stream = New MemoryStream 
    Dim TinyStream As Stream = New MemoryStream 
    Dim MidStream As Stream = New MemoryStream 
    Dim GridStream As Stream = New MemoryStream 
    Dim ListStream As Stream = New MemoryStream 


    Dim c As New ImageResizer.Configuration.Config 

    Dim SourceImage As Bitmap = New Bitmap(imgStream) 
    Dim SourceMain As Bitmap = New Bitmap(SourceImage) 
    Dim SourceHome As Bitmap = New Bitmap(SourceImage) 
    Dim SourceSmall As Bitmap = New Bitmap(SourceImage) 
    Dim SourceTiny As Bitmap = New Bitmap(SourceImage) 
    Dim SourceMid As Bitmap = New Bitmap(SourceImage) 
    Dim SourceGrid As Bitmap = New Bitmap(SourceImage) 
    Dim SourceList As Bitmap = New Bitmap(SourceImage) 

    ImageResizer.ImageBuilder.Current.Build(SourceMain, MainStream, New ResizeSettings("width=300&height=372&scale=both&paddingWidth=40")) 'ProductPage 
    ImageResizer.ImageBuilder.Current.Build(SourceHome, HomeStream, New ResizeSettings("width=112&height=147&scale=both")) 'HomePage Products 
    ImageResizer.ImageBuilder.Current.Build(SourceGrid, GridStream, New ResizeSettings("width=149&height=149&scale=both")) 'Categories Grid 
    ImageResizer.ImageBuilder.Current.Build(SourceList, ListStream, New ResizeSettings("width=171&height=206&scale=both")) 'Categories List 
    ImageResizer.ImageBuilder.Current.Build(SourceSmall, SmallStream, New ResizeSettings("width=64&height=75&scale=both")) 'Accessories 
    ImageResizer.ImageBuilder.Current.Build(SourceTiny, TinyStream, New ResizeSettings("width=82&height=82&scale=both")) 'Cart 
    ImageResizer.ImageBuilder.Current.Build(SourceMid, MidStream, New ResizeSettings("width=155&height=116&scale=both")) 'CategoryMain 


    AmazonUploadFile("OriginalImages/" & imgName, imgStream) 
    AmazonUploadFile("MainImages/" & imgName, MainStream) 
    AmazonUploadFile("HomeImages/" & imgName, HomeStream) 
    AmazonUploadFile("GridImages/" & imgName, GridStream) 
    AmazonUploadFile("ListImages/" & imgName, ListStream) 
    AmazonUploadFile("SmallImages/" & imgName, SmallStream) 
    AmazonUploadFile("TinyImages/" & imgName, TinyStream) 
    AmazonUploadFile("MidImages/" & imgName, MidStream) 
End Sub 

Public Shared Sub AmazonUploadFile(S3Key As String, FileStream As Stream) 
    Dim request As New PutObjectRequest() 
    request.WithBucketName(BUCKET_NAME) 
    request.WithKey(S3Key).InputStream = FileStream 
    request.WithCannedACL(S3CannedACL.PublicRead) 
    GetS3Client.PutObject(request) 
End Sub 

Antwort

3

Der folgende Codeausschnitt tun sollten, was Sie wollen:

Using myImage = Image.FromFile(fullImg) 
    Using ms As New MemoryStream() 
     myImage.Save(ms, ImageFormat.Jpeg) 
     ms.Seek(0, SeekOrigin.Begin) 
     UploadImage(ms, SKU) 
    End Using 
    End Using 

Als Nebenwirkung, könnten Sie feststellen, Es ist einfacher, Ihre Methoden zu parametrisieren und die ganze Arbeit zu erledigen, wenn Sie sie aufrufen. So etwas wie die folgenden können Ihr Leben leichter machen (unter Annahme der Code, den Sie geschrieben ist Code, den Sie tatsächlich verwenden und keine Demo):

Public Shared Sub UploadImages() 
    'Call this for each image 
    MoveToAmazon("C:\ImageLocation\blah.jpg", "OriginalImage", 300, 300, 0, "whatever") 

End Sub 


Public Shared Sub MoveToAmazon(strImg As String, targetFolder As String, height as Integer, width as Integer, padding as Integer, SKU As String) 
     Dim fullImg As String = "" & strImg 
     Using img = Image.FromFile(fullImg) 
      'Here Im missing the code to convert it to a stream. 
      Using ms As New MemoryStream() 
       Image.Save(ms, ImageFormat.Jpeg) 
       ms.Seek(0, SeekOrigin.Begin) 
       UploadImage(ms, SKU) 
      End Using 
     End Using 
End Sub 


Public Shared Sub UploadImage(imgStream As Stream, imgName As String, targetFolder As String, height as Integer, width as Integer, padding as Integer, SKU As String) 

    Dim c As New ImageResizer.Configuration.Config 

    ImageResizer.ImageBuilder.Current.Build(SourceMain, imgStream, New ResizeSettings("width=" & CStr(width) & "&height=" & CStr(height) & "&scale=both&paddingWidth=" & CStr(padding)) 

    AmazonUploadFile(targetFolder & "/" & imgName, imgStream) 

End Sub 

Public Shared Sub AmazonUploadFile(S3Key As String, FileStream As Stream) 
    Dim request As New PutObjectRequest() 
    request.WithBucketName(BUCKET_NAME) 
    request.WithKey(S3Key).InputStream = FileStream 
    request.WithCannedACL(S3CannedACL.PublicRead) 
    GetS3Client.PutObject(request) 
End Sub 


Using ms As New MemoryStream() 
    Image.Save(ms, ImageFormat.Jpeg) 
    ms.Seek(0, SeekOrigin.Begin) 
    UploadImage(ms, SKU) 
End Using 
+0

woher kommt die Funktion uploadedImage? – monsey11

+0

Ich bin neu bei .net und Streams. Kann ich ein .jpg Bild in einer Bitmap speichern? Ich benutze auch den Imageresizer, um Bilder mit Leerraum zu versehen. kann alles lokal gemacht werden? – monsey11

+0

Ja; Um Ihre erste Frage zu beantworten, obwohl das Objekt Bitmap heißt, repräsentiert es tatsächlich ein Bild. Also würden Sie System.Drawing.Imaging.ImageFormat.Jpeg verwenden - siehe http://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageformat.aspx – dash

2

Lesen Sie die Bild Bytes und Sie es dann wickeln in einem Memory

MemoryStream ms = new MemoryStrean(imageBytes); 
5

[Disclaimer - ich bin der Autor des ImageResizing.NET library der OP die Frage zu stellen.]

Leute - verwenden Sie nicht Bitmap und Image-Instanzen, wenn Sie es möglicherweise vermeiden können. Es gibt a giant list of pitfalls, die Ihren Server zum Absturz bringen. Verwenden Sie nichts von System.Drawing ohne einen serversicheren Wrapper um es herum.

@dash - Ihr Code ist fast richtig, abgesehen von den Speicherlecks.

Bilder entschlüsseln und kodieren sicher ist nicht einfach. Lassen Sie die ImageResizing.Net-Bibliothek damit umgehen.

Dim settings as New ResizeSettings("width=64&height=75&scale=both") 
Using ms As New MemoryStream() 
    ImageBuilder.Current.Build("C:\ImageLocation\" & strImg, ms, settings) 
    ms.Seek(0, SeekOrigin.Begin) 
    UploadImage(ms, SKU) 
End Using 

Laden Sie nie etwas in eine Bitmap- oder Image-Instanz, wenn Sie mehrere Versionen erstellen. Klonen Sie die Datei stattdessen in einen MemoryStream.

Using fs as New FileStream(...) 
    Using ms as MemoryStream = Util.StreamUtils.CopyStream(fs) 
    'For loop here with your setting variations 
    ms.Seek(0, SeekOrigin.Begin) 
    'Place upload and resize code here 
    'End Loop 
    End Using 
End Using 
+0

Er ändert nicht lokal die Größe, er verwendet einen Drittanbieterdienst, um das Bild zu skalieren. Die Frage ist, wie das Bild in einem Stream platziert werden soll. Die Tatsache, dass der Stream bei der Verwendung des Streams verwendet wird, sollte die Entsorgung von Ressourcen übernehmen, damit sie nicht ausläuft. Beachten Sie auch, dass wir die Bilder seit fast 5 Jahren lokal auf unserem eigenen Server skalieren. Dabei verwenden wir einen ähnlichen Ansatz wie in der SO-Frage, und ich habe nie Fehler gemacht. Daher müssen wir zustimmen, dass wir nicht zustimmen! Punkt 5) auf der von Ihnen geposteten Liste ist jedoch ziemlich interessant. – dash

+0

Sie sollten wahrscheinlich auch erwähnen, dass Sie der Autor der Bibliothek sind, auf die Sie verlinken. Sieht aber gut aus :-) – dash

+0

@dash ** Was Dienst von Drittanbietern? ** Er benutzt meine Bibliothek, http://imageresizing.net. Es ist eine lokal ausgeführte Bibliothek. Der Stream ist nicht das, worüber du dich sorgen solltest. MemoryStream-Instanzen in .NET 1-4 tun nichts, wenn sie entsorgt werden - sie warten nur auf GC. Was Sie zu Tode erschrecken müssen, besteht darin, diese Image- oder Bitmap-Instanz loszulassen, ohne dass sie sich in einer using() -Klausel befindet. Sie scheinen 10K zum GC zu sein, so dass es zaudert, bis Ihr Worker-Prozess die Speichergrenzen wieder erreicht, was unter Last alle 500ms passieren kann. –