Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[XAML] Upload een image (control, geen file)

Pagina: 1
Acties:

  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
Ik ben op zoek naar een methode om vanuit een Windows 8 app een afbeelding te kunnen uploaden naar een web api (welke al geschreven is en werkt), maar de afbeelding zit in de UI in een image control, dus de afbeelding is niet opgeslagen als file.

Ik vind het zonde om de afbeelding eerst lokaal op te gaan slaan om hem daarna te uploaden en daarna lokaal weer te wissen, wat ik nu als tussenoplossing doe...

Ik ben tot nu toe alleen oplossingen tegengekomen om images als file te uploaden, niet vanuit een image control.

[ Voor 3% gewijzigd door Swerfer op 14-12-2012 21:18 . Reden: typo ]

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • jip_86
  • Registratie: Juli 2004
  • Laatst online: 23-11 16:07
Wat moet je aan die api leveren? Opzich zijn er genoeg manieren om dat in memory te doen. Makkelijkst is dan om eerst even te kijken wat die api verwacht.

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Helaas bevat de System.Net namespace voor Windows Store apps geen WebClient class welke dit een stuk gemakkelijk had gemaakt..

Je zult zelf een multi-part form post request moeten opbouwen zoals hier wordt gedaan: http://cristiroma.wordpre...n-c-using-httpwebrequest/

Microsoft heeft echter wel de System.ServiceModel namespace behouden omdat men WCF (web) services juist hiervoor een betere oplossing bied. Je zou eventueel ook naar ServiceStack kunnen kijken.. Form posts nabouwen vanuit een desktop client is niet de meest optimale methode en is eigenlijk alleen aan te raden als je geen toegang tot de server hebt..

If it isn't broken, fix it until it is..


  • Caelorum
  • Registratie: April 2005
  • Laatst online: 00:38
WebClient is vervangen door HttpClient

  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
jip_86 schreef op vrijdag 14 december 2012 @ 22:53:
Wat moet je aan die api leveren? Opzich zijn er genoeg manieren om dat in memory te doen. Makkelijkst is dan om eerst even te kijken wat die api verwacht.
De wep api verwacht een multipart httprequest.

Onderstaande code is hoe ik nu een imagefile upload vanuit de client en daaronder de code van de wep api:

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
Async Function UploadRecipePicture(image As IStorageFile, RecipeID As String) As Task
    If Variable.ConnectedToInternet Then
        Dim parts As New List(Of BackgroundTransferContentPart)()
        Dim part As New BackgroundTransferContentPart("File", "filename.jpg")
        part.SetFile(image)
        parts.Add(part)
        Dim uri As System.Uri = New System.Uri(Variable.WebApiUri & "UploadImage")
        Dim uploader As New BackgroundUploader()
        Dim upload As UploadOperation = Await uploader.CreateUploadAsync(uri, parts)
        uploader.SetRequestHeader("Filename", "filename.jpg")
        Await upload.StartAsync
    End If
End Function

Wep api:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Public Class UploadImageController
    Inherits ApiController

    Public Async Function PostFile() As Task(Of HttpResponseMessage)
        If Not Request.Content.IsMimeMultipartContent() Then
            Throw New HttpResponseException(HttpStatusCode.UnsupportedMediaType)
        End If
        Dim root As String = HttpContext.Current.Server.MapPath("~/User")
        Dim provider = New CustomMultipartFormDataStreamProvider(root)
        Try
            Await Request.Content.ReadAsMultipartAsync(provider)
            Return New HttpResponseMessage(HttpStatusCode.OK)
        Catch e As System.Exception
            Return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e)
        End Try
    End Function

End Class

Public Class CustomMultipartFormDataStreamProvider
    Inherits MultipartFormDataStreamProvider

    Public Sub New(path As String)
        MyBase.New(path)
    End Sub

    Public Overrides Function GetLocalFileName(headers As System.Net.Http.Headers.HttpContentHeaders) As String
        Dim name = If(Not String.IsNullOrWhiteSpace(headers.ContentDisposition.FileName), headers.ContentDisposition.FileName, "NoName")
        Return name.Replace("""", String.Empty)
        'this is here because Chrome submits files in quotation marks which get treated as part of the filename and get escaped
    End Function
End Class


Nu wil ik dus geen image file uploaden, maar een image vanuit een image control.

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Mij lijkt BackgroundUploader.CreateUploadFromStream geschikt, als je een IInputStream op je image te pakken kunt krijgen.

"Any sufficiently advanced technology is indistinguishable from magic."


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Misschien een rare vraag, maar hoe krijg jij dan een image in je image control?
Image control is alleen een image viewer. Waarschijnlijk wordt de image toegewezen via een OpenFilePicker. Waarom zou je die locatie niet gewoon hergebruiken voor de upload?

If it isn't broken, fix it until it is..


  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
Niemand_Anders schreef op zaterdag 15 december 2012 @ 12:31:
Misschien een rare vraag, maar hoe krijg jij dan een image in je image control?
Image control is alleen een image viewer. Waarschijnlijk wordt de image toegewezen via een OpenFilePicker. Waarom zou je die locatie niet gewoon hergebruiken voor de upload?
De afbeelding wordt inderdaad via een filepicker gekozen, maar na wat bewerkingen wil ik de afbeelding daarna direct uploaden, zonder eerst de afbeelding tijdelijk op te slaan...

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • Caelorum
  • Registratie: April 2005
  • Laatst online: 00:38
Swerfer schreef op zaterdag 15 december 2012 @ 14:55:
[...] zonder eerst de afbeelding tijdelijk op te slaan...
Als je het kan opslaan, kan je het toch ook gewoon in het geheugen zetten?

  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
Caelorum schreef op zaterdag 15 december 2012 @ 15:18:
[...]

Als je het kan opslaan, kan je het toch ook gewoon in het geheugen zetten?
Ja het staat al in het geheugen, in een image control. Maar nu moet ik de afbeelding nog kunnen uploaden naar de wep api. Een image file uploaden is geen probleem, maar een image uit een image control daar heb ik de juiste methode(s) nog niet voor gevonden...

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • Caelorum
  • Registratie: April 2005
  • Laatst online: 00:38
Swerfer schreef op zaterdag 15 december 2012 @ 15:42:
[...] Ja het staat al in het geheugen, in een image control. Maar nu moet ik de afbeelding nog kunnen uploaden naar de wep api. Een image file uploaden is geen probleem, maar een image uit een image control daar heb ik de juiste methode(s) nog niet voor gevonden...
Wat ik bedoel is als je al bij de data kan van de image om deze op te slaan, waarom kan je dan niet gewoon die laatste stap weglaten en de data direct uploaden? Komt nog bij dat je de file ook in een WriteableBitmap kan laden, bewerkingen hierop kan doen en deze als BitmapSource gebruikt voor de Image control.

  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
Caelorum schreef op zaterdag 15 december 2012 @ 16:33:
[...]

Wat ik bedoel is als je al bij de data kan van de image om deze op te slaan, waarom kan je dan niet gewoon die laatste stap weglaten en de data direct uploaden?
Dat is precies wat ik wil, maar daar kan ik de juiste methode niet voor vinden, om de data direct te uploaden. Ik weet alleen een methode om een file te uploaden...

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • Caelorum
  • Registratie: April 2005
  • Laatst online: 00:38
Dan schrijf je die image data in een MemoryStream oid weg en maak je met die Stream een HttpContent object aan. Die HttpContent object post je vervolgens met HttpClient.PostAsync(String, HttpContent) (al dan niet in een MultipartContent) naar je webservice.
Zoiets zou het dan moeten worden.

  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
*Kick*

Ik ben nog steeds geen methode tegengekomen, of ik weet ze niet te implementeren.

@Hierboven, ik heb een en ander geprobeerd, maar het lukt mij niet om de image in een memorystream of zo te plaatsen. Ik heb daar te weinig ervaring mee...

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 17-11 15:31
Als je je plaatje wilt uploaden zal je het moeten encoden in één of ander formaat (bijv .gif of .jpg of .png).

Je Image Control heeft een property Source (type BitmapSource of BitmapImage) die als het goed is je plaatje bevat en deze kan je encoden.
Hier een voorbeeldje:
http://msdn.microsoft.com/en-us/library/aa970689.aspx

[ Voor 27% gewijzigd door epic007 op 19-12-2012 15:20 ]


  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
Ik heb mijn upload functie aangepast en die kan nu een image in een stream uploaden:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
Async Function UploadAccountPicture(stream As Stream) As Task
    If Variable.ConnectedToInternet Then
        Dim uploaduri As String = "http://webapi.mysite.com/UploadImage"
        Dim httpClient As HttpClient = New HttpClient()
        Dim content As New MultipartFormDataContent
        content.Add(New StreamContent(Stream), "file", "picture.jpg")
        Dim msg As New HttpRequestMessage
        msg.Method = HttpMethod.Post
        msg.Content = content
        msg.RequestUri = New Uri(uploaduri)
        Await httpClient.SendAsync(msg)
    End If
End Function

Maar waar ik nu niet uit kom is hoe ik de image (bevind zich in een image control) kan omzetten naar een stream.

[ Voor 3% gewijzigd door Swerfer op 22-12-2012 14:31 ]

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
*Kick*

Ik heb vooral gezocht tussen de WPF en Phone forums en dergelijke en wel een hoop methoden gevonden, echter zijn die allemaal niet om te zetten in Windows 8 Xaml...

En zoeken naar Windows 8 voorbeelden heeft geen resultaat opgeleverd.

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Misschien even een stapje terug. Het image komt toch ook niet op magische wijze in een Image control? Er moet toch ergens een keer een uri/resource/stream/byte[]/whatever te pakken te krijgen zijn waar (de bytes van) dat plaatje uit te halen is?

"Any sufficiently advanced technology is indistinguishable from magic."


  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
Herko_ter_Horst schreef op vrijdag 28 december 2012 @ 17:41:
Misschien even een stapje terug. Het image komt toch ook niet op magische wijze in een Image control? Er moet toch ergens een keer een uri/resource/stream/byte[]/whatever te pakken te krijgen zijn waar (de bytes van) dat plaatje uit te halen is?
Ik laad de image als file, maar daarna moet de image worden aangepast (formaat) en wil ik deze zonder hem lokaal eerst op te hoeven slaan direct naar een web api sturen. Dus rechtstreeks de afbeelding vanuit een bitmapimage die ik resize en dan naar de web api wil versturen met een methode die een image in een stream verwacht (zie 3 posts hoger)...

Ik laad de image via een filepicker, die er dus een StorageFile van maakt. Deze zet ik dan in een bitmapimage die ik als source van de imagecontrol geef.

Kortom, ik moet dus van een bitmapimage terug naar een stream...

[ Voor 4% gewijzigd door Swerfer op 28-12-2012 21:42 ]

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 19-11 21:48
Eindelijk gelukt...

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Using fileStream As IRandomAccessStream = Await blaat.OpenAsync(Windows.Storage.FileAccessMode.Read)
    Dim bitmapImage As New BitmapImage
    Await bitmapImage.SetSourceAsync(fileStream)
    Dim decoder = Await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(fileStream)
    Dim memStream = New Windows.Storage.Streams.InMemoryRandomAccessStream()
    Dim encoder = Await Windows.Graphics.Imaging.BitmapEncoder.CreateForTranscodingAsync(memStream, decoder)
    Dim width = bitmapImage.PixelWidth
    Dim height = bitmapImage.PixelHeight
    If width > 956 Or height > 718 Then
        If height > width Then
            encoder.BitmapTransform.ScaledHeight = 719
            encoder.BitmapTransform.ScaledWidth = 719 / (height / width)
        Else
            encoder.BitmapTransform.ScaledWidth = 957
            encoder.BitmapTransform.ScaledHeight = 957 / (width / height)
        End If
    End If
    encoder.BitmapTransform.InterpolationMode = Windows.Graphics.Imaging.BitmapInterpolationMode.Fant
    encoder.IsThumbnailGenerated = False
    Await encoder.FlushAsync()
    memStream.Seek(0)
End Using

De memStream bevat nu de image in een InMemoryRandomAccessStream welke geaccepteerd wordt door mijn functie om de afbeelding te uploaden naar de web api. (memStream.AsStream)

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com

Pagina: 1