2012-03-30 188 views
4

我使用上传图像,使用流并使用imageresizer.net调整大小,然后将该流上传到Amazon S3的函数。将图像转换为流

现在我想拍摄一张本地图片并将其转换为流。 (调整并上传到amazonS3)。基本上,你如何将图像转换为流。

这可能是一个简单的问题,只是无法在任何地方找到答案。

这里是一些基本的代码。

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 

回答

3

下面的代码段应该做你想要什么:

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 

顺便说一句,你可能会发现它更容易参数化您的方法,并在调用它们时完成所有工作。像下面的内容可能会让你的生活更轻松(这是假设你发布的代码是你实际使用的代码,而不是一个演示):

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

其中函数uploadedImage来自哪里? – monsey11 2012-04-02 13:46:52

+0

我是新来的.net和流。我可以将.jpg图像保存到位图吗?我也在使用imageresizer为图像添加空白区域。这一切都可以在本地完成吗? – monsey11 2012-04-02 13:51:37

+0

是的;回答你的第一个问题,尽管该对象称为位图,但它实际上代表了一个图像。所以你会使用System.Drawing.Imaging.ImageFormat.Jpeg - 请参阅http://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageformat.aspx – dash 2012-04-02 14:06:11

2

阅读图像的字节数,然后你把它包装在一个MemoryStream

MemoryStream ms = new MemoryStrean(imageBytes); 
5

[免责声明 - 我是ImageResizing.NET library笔者的OP是问关于的问题。]

民间 - 不要使用位图和图像实例,如果你可以避免它。有a giant list of pitfalls会导致你的服务器崩溃。不要在System.Drawing中使用任何没有服务器安全包装的任何东西。

@dash - 你的代码几乎是正确的,除了内存泄漏。

安全地解码和编码图像并不简单。让ImageResizing.Net库处理它。

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 

如果您制作多个版本,切勿将某些东西加载到位图或图像实例中。相反,将文件克隆到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

他没有在本地调整大小,他使用第三方服务来调整图像大小。问题是关于如何将图像放入流中。流包裹使用的事实应该处理资源的处置,因此它不应该泄漏。另外请注意,我们已经使用与链接的SO问题类似的方法在我们自己的服务器上本地调整图像大小5年,并且它从未发生错误,因此我们必须同意不同意!但是,你发布的名单上的第5)点非常有趣。 – dash 2012-04-04 14:53:19

+0

您应该也可以提及您是您链接到的图书馆的作者。看起来不错,但:-) – dash 2012-04-04 14:57:07

+0

@dash **什么第三方服务?**他使用我的图书馆,http://imageresizing.net。这是一个本地执行的库。这个流不是你应该担心的。 .NET 1-4中的MemoryStream实例在处置时甚至不会执行任何操作 - 它们只是等待GC。你需要**吓到死亡**是让Image或Bitmap实例在没有使用using()子句的情况下运行。它们似乎是GC的10K,因此它会拖延,直到您的工作进程从内存限制中循环,这可能会在负载下每500毫秒发生一次。 – 2012-04-04 15:03:44