c# - Creating thumbnail of image on Windows Phone 8 in threadpool -
c# - Creating thumbnail of image on Windows Phone 8 in threadpool -
i need create thumbnail of image on wp8, , i'm facing difficulties. in nutshell, know 1 way of doing this, using classes system.windows.controls.image
, system.windows.media.imaging.bitmapimage
, system.windows.media.imaging.writablebitmap
. i'm trying perform thumbnail creation on threadpool, because it's part of other bigger operation, running on threadpool.
as have understood, i'm failing invalid cross-thread access, when i'm trying create instance of above classes. that's shame, really, because thumbnail not going used in ui, saved file, , displayed file later on. work has nil ui thread, , i'm still facing limitations.
so there other way of creating thumbnail image stream (i'm getting photochooser task)? maybe other api, doesn't require ui-bound classes? tried bing it, google it, no luck.
okay, think i'll set own reply here well, since shows things bit of different perspective. reply justin angel okay, there's couple of issues it:
it's not possible have reference dispatcher, when code deep in model layer , running on background thread. i need homecoming thumbnail image method , utilize later in same synchronization context. otherwise i'll have alter lot of code around method of creating thumbnail.with requirements in mind, here's solution:
private writeablebitmap createthumbnail(stream stream, int width, int height, synchronizationcontext uithread) { // hack comes problem classes bitmapimage, writablebitmap, image used here // created or accessed ui thread. , code called threadpool. avoid // cross-thread access exceptions, dispatch code ui thread, waiting finish // using monitor , lock object, , homecoming value method. quite hacky, // way create work currently. it's quite stupid ms didn't provide classes image // processing on non-ui threads. writeablebitmap result = null; var waithandle = new object(); lock (waithandle) { uithread.post(_ => { lock (waithandle) { var bi = new bitmapimage(); bi.setsource(stream); int w, h; double ws = (double)width / bi.pixelwidth; double hs = (double)height / bi.pixelheight; double scale = (ws > hs) ? ws : hs; w = (int)(bi.pixelwidth * scale); h = (int)(bi.pixelheight * scale); var im = new image(); im.stretch = stretch.uniformtofill; im.source = bi; result = new writeablebitmap(width, height); var tr = new compositetransform(); tr.centerx = (ws > hs) ? 0 : (width - w) / 2; tr.centery = (ws < hs) ? 0 : (height - h) / 2; tr.scalex = scale; tr.scaley = scale; result.render(im, tr); result.invalidate(); monitor.pulse(waithandle); } }, null); monitor.wait(waithandle); } homecoming result; }
i'm capturing ui thread's synchronizationcontext while i'm still in ui thread (in view model), , passing further, , i'm using closures capture local variables, they're available callback runs on ui thread. i'm using lock , monitor synchronize these 2 threads , wait until image ready.
i'll take or justin angel's reply based on votes, if any. :)
edit: can instance of dispatcher's synchronizationcontext
through system.threading.synchronizationcontext.current
while you're on ui thread (in button click handler, example). this:
private async void createthumbnailbutton_clicked(object sender, eventargs args) { synchronizationcontext uithread = synchronizationcontext.current; var result = await task.factory.startnew<writeablebitmap>(() => { stream img = getoriginalimage();// original image through long synchronous operation homecoming createthumbnail(img, 163, 163, uithread); }); await savethumbnailasync(result); }
c# image-processing windows-phone-8 threadpool
Comments
Post a Comment