I'm using Xamarin to build an Android app in c#.
The problem I'm having is that I need to load a part of an image without loading the whole image first. I have a rectangle of the region I want from the image.
I found this solution for normal Android : BitmapRegionDecoder
However when I try to invoke this class in my Xamarin project it's not there and I can't import it either.
I looked in the API and it says that it should be there.Android.Graphics.BitmapRegionDecoder documentation
Does anyone know if it's possible to use this class or if there is another way to achieve this?
Note that it says it is present in API level 10, hence you have to set your minimum target to 10 in the Application properties.
Then you can use it like so:
using (var inStream = ContentResolver.OpenInputStream(Android.Net.Uri.Parse("YourBitmapUri")))
{
using (var decoder = BitmapRegionDecoder.NewInstance(inStream, false))
{
var bitmap = decoder.DecodeRegion(YourRect, new BitmapFactory.Options());
// use your bitmap i.e. for an ImageView
bitmap.Dispose();
}
}
Related
I want to draw something with GPU acceleration (using OpenGL or Vulkan) using SkiaSharp and save the image later. There is no need to display the image anywhere in the application, because it's a console application targeting Windows and Linux.
I already tried the following code, with various variations, but nothing worked (raises an exception at var surface = SKSurface.Create(context, false, info); because glInterface and context are null.
Can somebody give me a hint?
var glInterface = GRGlInterface.Create();
var context = GRContext.CreateGl(glInterface);
var info = new SKImageInfo(256, 256);
var surface = SKSurface.Create(context, false, info);
var canvas = surface.Canvas;
In the end it would be nice to have the ability to call SKBitmap.SetPixels(IntPrt) or something similar to set the resulting bitmap buffer to a specific place.
The solution is you need to manually create an OpenGL context first.
Have a look at https://github.com/mono/SkiaSharp/blob/master/tests/Tests/GRContextTest.cs for implementation details.
For copying the rendered pixel buffer you can use SKSurface.ReadPixels.
I have written a windows store app in XAML & C# to read image from tablet's webcam and decode the barcode using Zxing's lbrary. The code is working fine on a given tablet having an i5 processor while it fails to run on an actual tablet with 2MP camera and "Intel Baytrail Quad-Core" processor.
Any ideas on why this could happen?
Please let me know if you need to see my code for this issue ad I will share.
I am wondering how can the same code work on 1 tablet while fail on another tablet.
Thanks in advance for any help provided.
EDIT
Code used to scan the barcode and read as below - The last if/else block is what I get to. No exception raised :(
string barcodeData = string.Empty;
using (var imageStream = new InMemoryRandomAccessStream())
{
processingImage = true;
var encodingProperties = new ImageEncodingProperties();
encodingProperties.Subtype = "Jpeg";
encodingProperties.Width = 400;
encodingProperties.Height = 400;
await captureMgr.CapturePhotoToStreamAsync(encodingProperties, imageStream);
await imageStream.FlushAsync();
imageStream.Seek(0);
var bitmap = new WriteableBitmap(400, 400);
bitmap.SetSource(imageStream);
preview1.Source = bitmap; //preview1 is an Image control to display the captured image
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(imageStream);
imageStream.Seek(0);
var bitmapDecoder = await BitmapDecoder.CreateAsync(BitmapDecoder.JpegDecoderId, imageStream);
var data = await bitmapDecoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Straight,
new BitmapTransform(),
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.DoNotColorManage
);
if (data != null)
{
BarcodeReader barcodeReader = new BarcodeReader();
var result = barcodeReader.Decode(
data.DetachPixelData(),
(int)bitmapDecoder.PixelWidth,
(int)bitmapDecoder.PixelHeight,
ZXing.RGBLuminanceSource.BitmapFormat.BGR32
);
if (result != null)
{
//Barcode found
}
else
//No data found.
}
}
I guess you are using ZXing.NET library.
Have you ever considered moving to another barcode scanner library?
Accessing the "ISSUES" section in ZXing.NET Library, you can see that there's a lot of bugs still opened for Windows Phone (and should be Window Store also).
http://zxingnet.codeplex.com/workitem/list/basic
One of it called my attention. Check out this comment:
While the WP samples all target Silverlight, you must not forget that the new WP8.1 base is WinRT - so I suggest you use the WinRT sample as a base.
I tried to do the same, but truth to be told, ZXing lacks a lot ATM for WinRT Universal Apps - it's slow, unreliable, and barely ever recognizes a thing.
http://zxingnet.codeplex.com/workitem/13311
I don't know how reliable this is, but the last time the project was updated was on April 7th!!!!
You should really consider changing you library!
Hi,
I made a lib for WinRT using ZXing & Imaging SDK.
It works well (but does not include any additional focus feature).
https://github.com/stepheUp/VideoScanZXing4WP81
There is a lib and a sample app that you can try.
It works for barcodes and QRCode (barcode by default but just change the optional parameter in the scan function code to use QRCode)
Hope it helps,
Stéphanie
I want to draw lines as fast as possible. For that reason I implemented a method using InteropBitmap. This works quite good. Next step was to compare with ShardDX. Basically what I want to do is:
Running the following code in a BackgroundWorker. This does inform the WPF about an update of WIC. I found out that this code (creating all needed for ShapeDX and draw line) takes about 10ms longer than doing the same using InteropBitmap.
My question now is simply, how to speed this up? Can I change the code somehow that I only have to call BeginDraw, create lines and EndDraw, not always doing all of this Image Encoding/Decoding stuff? Or is there a better approach?
var wicFactory = new ImagingFactory();
var d2dFactory = new SharpDX.Direct2D1.Factory();
const int width = 800;
const int height = 200;
var wicBitmap = new Bitmap(wicFactory, width, height, SharpDX.WIC.PixelFormat.Format32bppBGR, BitmapCreateCacheOption.CacheOnLoad);
var renderTargetProperties = new RenderTargetProperties(RenderTargetType.Default, new PixelFormat(Format.Unknown, AlphaMode.Unknown), 0, 0, RenderTargetUsage.None, FeatureLevel.Level_DEFAULT);
var d2dRenderTarget = new WicRenderTarget(d2dFactory, wicBitmap, renderTargetProperties);
var solidColorBrush = new SharpDX.Direct2D1.SolidColorBrush(d2dRenderTarget, SharpDX.Color.White);
d2dRenderTarget.BeginDraw();
//draw whatever you want
d2dRenderTarget.EndDraw();
// Memorystream.
MemoryStream ms = new MemoryStream();
var stream = new WICStream(wicFactory, ms);
// JPEG encoder
var encoder = new SharpDX.WIC.JpegBitmapEncoder(wicFactory);
encoder.Initialize(stream);
// Frame encoder
var bitmapFrameEncode = new BitmapFrameEncode(encoder);
bitmapFrameEncode.Initialize();
bitmapFrameEncode.SetSize(width, height);
var pixelFormatGuid = SharpDX.WIC.PixelFormat.FormatDontCare;
bitmapFrameEncode.SetPixelFormat(ref pixelFormatGuid);
bitmapFrameEncode.WriteSource(wicBitmap);
bitmapFrameEncode.Commit();
encoder.Commit();
ms.Seek(0, SeekOrigin.Begin);
// JPEG decoder
var decoder = new System.Windows.Media.Imaging.JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
// Write to wpf image
_WIC = decoder.Frames[0];
// Tell WPF to update
RaisePropertyChanged("WIC");
bitmapFrameEncode.Dispose();
encoder.Dispose();
stream.Dispose();
With:
System.Windows.Media.Imaging.BitmapFrame _WIC;
public System.Windows.Media.Imaging.BitmapSource WIC
{
get
{
return (System.Windows.Media.Imaging.BitmapSource)_WIC.GetAsFrozen();
}
}
And:
<StackPanel>
<Image Name="huhu1" Source="{Binding WIC}" />
</StackPanel>
SharpDX Toolkit has support for WPF via a Direct3D11-to-Direct3D9 shared texture. It is implemented in the SharpDXElement class.
You may not be able to reuse this as is because Direct2D (which you are using to draw) can interop either with Direct3D11.1 or Direct3D10 and SharpDX uses Direct3D11 for WPF support, so you will need to tweak the solution a little bit.
Basically you need to do the following:
Initialize Direct3D (10 or 11.1).
Initialize Direct2D.
Create the D3D render target with Direct2D support and the Shared flag (here is how it is done in SharpDX).
Initialize Direct3D9.
Create the shared texture.
Bind the texture to an D3DImage.
Do not forget to call D3DImage.AddDirtyRect when the contents of the render target are updated.
From the code you provided it is not clear if you are doing all initializations only once or not, so try to call any initialization code only once and reuse the render target - just clear it at the beginning of every frame. This is mandatory to get a decent performance.
Update: SharpDX.Toolkit has been deprecated and it is not maintained anymore. It is moved to a separate repository.
If you want to share a directx surface with WPF, the best option is using a WPF D3DImage. It promises to work without copying if you use the right color format.
I have only used it with Directx9, but it is possible that its compatible with Direct2D too, but if it isn't D3d9 can draw lines too.
There's a great codeproject article with examples. From managed code using slimdx or sharpdx the only nonobvious caveat is that D3DImage retains a reference count to your DirectX surface, so you need to null the backbuffer expicitly when you want to reset your d3d device.
You can use Smartrak/WpfSharpDxControl: Provides WPF control to host SharpDx content.
It uses sharpDx in WPF and the wpf can add Win32HwndControl to HwndHost.
I want to export an image of my ArcGIS map object with the graphics layer on it. I've tried esri's own web services for export but they're not so efficient and clear, not supporting complex geometric shapes also they're not support local layers such as Google map provider. Service supports only ArcGISTiledLayer i want it in all layers. So, i searched in their forums but they say they won't support local layers until next versions.
I've tried ImageTool libraries and WritableBitmapEx libraries in codeplex. But when i try to get byte[] from a WritableBitmap i can not access its Pixels property for some security reasons all the time. Application throws a SecurityException and says that 'you can't access this pixels property'.
So, is there any way for get a UIElement control's image and save it to the disk? Or is there a workaround for this security exception?
Yes the image tools library has a method to do this into png/jpg etc.
http://imagetools.codeplex.com/
Also you can use RenderTargetBitmap - http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.rendertargetbitmap.aspx
Here is an example of how to save a file to disk. you can only do it from a dialog
http://www.silverlightshow.net/items/Using-the-SaveFileDialog-in-Silverlight-3.aspx
EDIT - Sample Code
Calling
var objImage = new WritableBitmap(MyElement, MyElement.RenderTransform);
var bytData = objImage.ToPng();
Extension Method
using ImageTools.IO.Png;
using ImageTools;
public static byte[] ToPng(this WriteableBitmap Image)
{
byte[] bytResult;
using (MemoryStream objPngStream = new MemoryStream())
{
PngEncoder objPngEncoder = new PngEncoder();
objPngEncoder.Encode(Image.ToImage(), objPngStream);
objPngStream.Seek(0, SeekOrigin.Begin);
bytResult = objPngStream.ToArray();
objPngStream.Close();
}
return bytResult;
}
I'm trying to make a Windows Phone 7 app that will save some images off the web, I have no idea where I can or if I can save images from the web to the phone.
What can I do to save images?
You can download them using WebClient or WebRequest to get the raw bytes.
You can then save to isolated storage fairly easily - but I don't believe you can save in any location seen by the Picture hub, if that's what you were aiming for. (I can't see anything in the Microsoft.Phone.Tasks namespace which would be relevant. There are tasks to capture the camera of choose a photo, but not to save one.)
EDIT: Ooh, I've just found a way. You can use the MediaLibrary class and its SavePicture method... although that's in XNA, so I'd at least have concerns about it working from a Silverlight app. I know some bits of the XNA API do work from Silverlight, and some don't. Worth experimenting with.
On the phone, you can use HttbWebRequest (recommended to avoid UI impact) or WebClient per the project I posted here.
WebClient, HttpWebRequest and the UI Thread on Windows Phone 7
You can then take your stream and pass it into something of this form to write it to isolated storage.
private void PicToIsoStore(Stream pic) {
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication()) {
var bi = new BitmapImage();
bi.SetSource(pic);
var wb = new WriteableBitmap(bi);
using (var isoFileStream = isoStore.CreateFile("somepic.jpg")) {
var width = wb.PixelWidth;
var height = wb.PixelHeight;
Extensions.SaveJpeg(wb, isoFileStream, width, height, 0, 100);
}
}
}
Jon is correct you can also use MediaLibrary.SavePicture. Be aware that this would put the pics mixed in with the users photos in the Picture Hub.
This is as straight forward as
private void PicToMediaLibary(Stream pic) {
MediaLibrary lib = new MediaLibrary();
lib.SavePicture("blah", pic);
}
Storing it in isolated storage is basically your apps private file system.