void LoadBitmapData (int texId) { NSData texData = NSData.FromFile (NSBundle.MainBundle.PathForResource ("texture1", "png")); UIImage image = UIImage.LoadFromData (texData); if (image == null) return; int width = image.CGImage.Width; int height = image.CGImage.Height; CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB (); byte[] imageData = new byte[height * width * 4]; CGContext context = new CGBitmapContext (imageData, width, height, 8, 4 * width, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrder32Big); context.TranslateCTM (0, height); context.ScaleCTM (1, -1); colorSpace.Dispose (); context.ClearRect (new RectangleF (0, 0, width, height)); context.DrawImage (new RectangleF (0, 0, width, height), image.CGImage); GL.TexImage2D (TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, imageData); context.Dispose (); }
public static UIImage AddImageReflection(UIImage image, float reflectionFraction) { int reflectionHeight = (int) (image.Size.Height * reflectionFraction); // Create a 2 bit CGImage containing a gradient that will be used for masking the // main view content to create the 'fade' of the reflection. The CGImageCreateWithMask // function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient // gradient is always black and white and the mask must be in the gray colorspace var colorSpace = CGColorSpace.CreateDeviceGray (); // Creat the bitmap context var gradientBitmapContext = new CGBitmapContext (IntPtr.Zero, 1, reflectionHeight, 8, 0, colorSpace, CGImageAlphaInfo.None); // define the start and end grayscale values (with the alpha, even though // our bitmap context doesn't support alpha the gradien requires it) float [] colors = { 0, 1, 1, 1 }; // Create the CGGradient and then release the gray color space var grayScaleGradient = new CGGradient (colorSpace, colors, null); colorSpace.Dispose (); // create the start and end points for the gradient vector (straight down) var gradientStartPoint = new PointF (0, reflectionHeight); var gradientEndPoint = PointF.Empty; // draw the gradient into the gray bitmap context gradientBitmapContext.DrawLinearGradient (grayScaleGradient, gradientStartPoint, gradientEndPoint, CGGradientDrawingOptions.DrawsAfterEndLocation); grayScaleGradient.Dispose (); // Add a black fill with 50% opactiy gradientBitmapContext.SetGrayFillColor (0, 0.5f); gradientBitmapContext.FillRect (new RectangleF (0, 0, 1, reflectionHeight)); // conver the context into a CGImage and release the context var gradientImageMask = gradientBitmapContext.ToImage (); gradientBitmapContext.Dispose (); // create an image by masking the bitmap of the mainView content with the gradient view // then release the pre-masked content bitmap and the gradient bitmap var reflectionImage = image.CGImage.WithMask (gradientImageMask); gradientImageMask.Dispose (); var size = new SizeF (image.Size.Width, image.Size.Height + reflectionHeight); UIGraphics.BeginImageContext (size); image.Draw (PointF.Empty); var context = UIGraphics.GetCurrentContext (); context.DrawImage (new RectangleF (0, image.Size.Height, image.Size.Width, reflectionHeight), reflectionImage); var result = UIGraphics.GetImageFromCurrentImageContext (); UIGraphics.EndImageContext (); reflectionImage.Dispose (); return result; }
public IBitmapImplementation Rescale(int newWidth, int newHeight) { CGBitmapContext bctx = new CGBitmapContext(null, newWidth, newHeight, cgImage.BitsPerComponent, 0, CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedLast); bctx.InterpolationQuality = CGInterpolationQuality.High; bctx.DrawImage(new CGRect(0, 0, newWidth, newHeight), cgImage); var img = bctx.ToImage(); bctx.Dispose(); return(new BitmapImplementation(img)); }
private Texture(String filename) { #if __ANDROID__ AssetManager assets = GameActivity.Instance.Assets; Bitmap bitmap = null; using (Stream stream = assets.Open(filename)) { bitmap = BitmapFactory.DecodeStream(stream); Width = bitmap.Width; Height = bitmap.Height; } GL.GenTextures(1, out _GLID); GL.BindTexture(All.Texture2D, _GLID); GL.TexParameter(All.Texture2D, All.TextureWrapS, (Int32)All.Repeat); GL.TexParameter(All.Texture2D, All.TextureWrapT, (Int32)All.Repeat); GL.TexParameter(All.Texture2D, All.TextureMinFilter, (Int32)All.Linear); GL.TexParameter(All.Texture2D, All.TextureMagFilter, (Int32)All.Linear); GLUtils.TexImage2D((Int32)All.Texture2D, 0, bitmap, 0); GL.GenerateMipmap(All.Texture2D); GL.BindTexture(All.Texture2D, 0); bitmap.Recycle(); #elif __IOS__ UIImage image = UIImage.FromFile(filename); nint cgWidth = image.CGImage.Width; nint cgHeight = image.CGImage.Height; Width = (Int32)cgWidth; Height = (Int32)cgHeight; CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB(); Byte[] data = new Byte[Width * Height * 4]; CGContext context = new CGBitmapContext(data, cgWidth, cgHeight, 8, 4 * Width, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrderDefault); colorSpace.Dispose(); context.ClearRect(new CGRect(0, 0, cgWidth, cgHeight)); context.DrawImage(new CGRect(0, 0, cgWidth, cgHeight), image.CGImage); GL.GenTextures(1, out _GLID); GL.BindTexture(TextureTarget.Texture2D, _GLID); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (Int32)All.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (Int32)All.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (Int32)TextureMinFilter.LinearMipmapLinear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (Int32)TextureMagFilter.Linear); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, data); context.Dispose(); GL.GenerateMipmap(TextureTarget.Texture2D); GL.BindTexture(TextureTarget.Texture2D, 0); #endif LoadedTextures.Add(filename, this); _Filename = filename; }
public UIImage ProcessedImage() { nfloat scale = UIScreen.MainScreen.Scale; CGImage imageRef = _originalImage.CGImage; if (imageRef == null) { return(null); } var bytesPerRow = 0; var bitsPerComponent = imageRef.BitsPerComponent; CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB(); var bitmapInfo = imageRef.BitmapInfo; CGBitmapContext context = new CGBitmapContext(null, (nint)(_targetSize.Width * scale), (nint)(_targetSize.Height * scale), bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); colorSpace.Dispose(); if (context == null) { imageRef.Dispose(); return(null); } CGRect targetFrame = LocalCropFrame(); context.InterpolationQuality = CGInterpolationQuality.High; context.SetBlendMode(CGBlendMode.Copy); context.DrawImage(targetFrame, imageRef); var contextImage = context.ToImage(); UIImage finalImage = null; context.Dispose(); if (contextImage != null) { finalImage = UIImage.FromImage(contextImage, scale, UIImageOrientation.Up); contextImage.Dispose(); } imageRef.Dispose(); return(finalImage); }
/// <summary> /// Calculates the "average" color of the picture. /// i.e. average color = average R, average G, average B /// </summary> /// <param name="image">CGImage to calculate the average from.</param> /// <returns>average color</returns> public static UIColor AverageColor(CGImage image) { CGImage imageRef = image; nint width = (int)(imageRef.Width); nint height = (int)(imageRef.Height); nint count = width * height; CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB(); byte[] rawData = new byte[height * width * 4]; nint bytesPerPixel = 4; nint bytesPerRow = bytesPerPixel * width; nint bitsPerComponent = 8; CGContext context = new CGBitmapContext( rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, CGBitmapFlags.ByteOrder32Big | CGBitmapFlags.PremultipliedLast ); context.DrawImage(new CGRect(0, 0, width, height), imageRef); context.Dispose(); nint byteIndex = 0; float r = 0; float g = 0; float b = 0; for (int i = 0; i < count; i++) { float red = rawData[byteIndex]; float green = rawData[byteIndex + 1]; float blue = rawData[byteIndex + 2]; byteIndex += bytesPerPixel; r += (int)red; g += (int)green; b += (int)blue; } r = r / count / 255; g = g / count / 255; b = b / count / 255; return(new UIColor(red: r, green: g, blue: b, alpha: 1)); }
public GLTexture(string inFilename) { GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); filename = inFilename; GL.Hint(HintTarget.GenerateMipmapHint, HintMode.Nicest); GL.GenTextures(1, out texture); GL.BindTexture(TextureTarget.Texture2D, texture); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Nearest); //TODO Remove the Substring method if you don't support iOS versions prior to iOS 6. string extension = Path.GetExtension(filename).Substring(1); string baseFilename = Path.GetFileNameWithoutExtension(filename); string path = NSBundle.MainBundle.PathForResource(baseFilename, extension); NSData texData = NSData.FromFile(path); UIImage image = UIImage.LoadFromData(texData); if (image == null) { return; } nint width = image.CGImage.Width; nint height = image.CGImage.Height; CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB(); byte [] imageData = new byte[height * width * 4]; CGContext context = new CGBitmapContext(imageData, width, height, 8, 4 * width, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrder32Big); context.TranslateCTM(0, height); context.ScaleCTM(1, -1); colorSpace.Dispose(); context.ClearRect(new CGRect(0, 0, width, height)); context.DrawImage(new CGRect(0, 0, width, height), image.CGImage); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, (int)width, (int)height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, imageData); context.Dispose(); }
public static UIColor ColorAtPixel(CGPoint point, UIImage image) { CGRect rect = new CGRect(0, 0, image.Size.Width, image.Size.Height); // CancelIf pointIs outside Image coordinates if (!rect.Contains(point)) { return(null); } // Create a 1x1 pixel byte array and bitmap context to draw the pixelInto. // Reference: http://stackoverflow.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiImage int pointX = Convert.ToInt16(Math.Truncate(point.X)); int pointY = Convert.ToInt16(Math.Truncate(point.Y)); CGImage cgimage = image.CGImage; int width = Convert.ToInt16(image.Size.Width); int height = Convert.ToInt16(image.Size.Height); CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB(); int bytesPerPixel = 4; int bytesPerRow = bytesPerPixel * 1; int bitsPerComponent = 8; byte [] pixelData = { 0, 0, 0, 0 }; CGContext context = new CGBitmapContext(pixelData, 1, 1, bitsPerComponent, bytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedLast /*| CGBitmapFlags.ByteOrder32Big*/); // colorSpace.Dispose (); context.SetFillColorSpace(colorSpace); // CGColorSpaceRelease(colorSpace); //TODO Not Sure context.SetBlendMode(CGBlendMode.Copy); // Draw the pixel we areInterestedIn onto the bitmap context context.TranslateCTM(-pointX, pointY - (nfloat)height); context.DrawImage(new CGRect(0.0f, 0.0f, (nfloat)width, (nfloat)height), image.CGImage); context.Dispose(); // CGContextRelease(context); //TODO Not Sure // Convert color values [0..255] to floats [0.0..1.0] nfloat red = (nfloat)pixelData [0] / 255.0f; nfloat green = (nfloat)pixelData [1] / 255.0f; nfloat blue = (nfloat)pixelData [2] / 255.0f; nfloat alpha = (nfloat)pixelData [3] / 255.0f; return(UIColor.FromRGBA(red, green, blue, alpha)); }
public Size GetCharData(char c, out UInt32[] cdata) { NSString str = new NSString(c.ToString()); var size = str.StringSize(font); UIGraphics.BeginImageContextWithOptions(size, false, 1.0f); UIGraphics.GetCurrentContext().SetFillColor(1.0f, 1.0f, 1.0f, 1.0f); str.DrawString(new System.Drawing.PointF(0, 0), font); UIImage img = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); // int width = (int)size.Width; int height = (int)size.Height; cdata = new UInt32[width * height]; var gdata = new byte[width * height * 4]; var colorSpace = CGColorSpace.CreateDeviceRGB(); var gbmp = new CGBitmapContext(gdata, width, height, 8, width * 4, colorSpace, CGBitmapFlags.PremultipliedLast); //gbmp.ClearRect(new RectangleF(0,0,width,height)); gbmp.DrawImage(new System.Drawing.RectangleF(0, 0, width, height), img.CGImage); gbmp.Dispose(); colorSpace.Dispose(); unsafe { fixed(byte *srcb = gdata) fixed(UInt32 * dest = cdata) { UInt32 *src = (UInt32 *)srcb; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { dest[y * width + x] = src[y * width + x]; } } } } return(new Size(width, height)); }
public GLTexture (string inFilename) { GL.Enable (EnableCap.Texture2D); GL.Enable (EnableCap.Blend); filename = inFilename; GL.Hint (HintTarget.GenerateMipmapHint, HintMode.Nicest); GL.GenTextures (1, out texture); GL.BindTexture (TextureTarget.Texture2D, texture); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) All.Repeat); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) All.Repeat); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) All.Linear); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) All.Linear); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) All.Nearest); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) All.Nearest); //TODO Remove the Substring method if you don't support iOS versions prior to iOS 6. string extension = Path.GetExtension (filename).Substring(1); string baseFilename = Path.GetFileNameWithoutExtension (filename); string path = NSBundle.MainBundle.PathForResource (baseFilename, extension); NSData texData = NSData.FromFile (path); UIImage image = UIImage.LoadFromData (texData); if (image == null) return; nint width = image.CGImage.Width; nint height = image.CGImage.Height; CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB (); byte [] imageData = new byte[height * width * 4]; CGContext context = new CGBitmapContext (imageData, width, height, 8, 4 * width, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrder32Big); context.TranslateCTM (0, height); context.ScaleCTM (1, -1); colorSpace.Dispose (); context.ClearRect (new CGRect (0, 0, width, height)); context.DrawImage (new CGRect (0, 0, width, height), image.CGImage); GL.TexImage2D (TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, (int)width, (int)height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, imageData); context.Dispose (); }
public override void TouchesEnded(NSSet touches, UIEvent evt) { base.TouchesEnded(touches, evt); var touch = (UITouch)touches.AnyObject; var pt = touch.LocationInView(this); #if DEBUG Debug.WriteLine("OnColourChanged = [" + pt.X + "," + pt.Y + "]"); #endif // extract colour from where user touched var buffer = Marshal.AllocHGlobal((int)(Image.Size.Width * Image.Size.Height * 4)); var colorSpace = CGColorSpace.CreateDeviceRGB(); var context = new CGBitmapContext(buffer, (int)Image.Size.Width, (int)Image.Size.Height, 8, 4 * (int)Image.Size.Width, colorSpace, CGImageAlphaInfo.NoneSkipFirst); try { context.InterpolationQuality = CGInterpolationQuality.None; context.DrawImage(new Rectangle(0, 0, (int)Image.Size.Width, (int)Image.Size.Height), Image.CGImage); unsafe { var bufPtr = (byte *)((void *)buffer); int offset = (int)(4 * (Image.Size.Width * pt.Y + pt.X)); float alpha = (float)bufPtr[offset] / 255f; float red = (float)bufPtr[offset + 1] / 255f; float green = (float)bufPtr[offset + 2] / 255f; float blue = (float)bufPtr[offset + 3] / 255f; Color = new CGColor(red, green, blue, alpha); } } finally { context.Dispose(); colorSpace.Dispose(); Marshal.FreeHGlobal(buffer); } if (null != OnColourChanged) { OnColourChanged(this, null); } }
public static Tuple <Microsoft.Xna.Framework.Point, byte[]> GetiOSData(Stream stream) { using (var uiImage = UIImage.LoadFromData(NSData.FromStream(stream))) { var cgImage = uiImage.CGImage; var width = cgImage.Width; var height = cgImage.Height; var data = new byte[width * height * 4]; var colorSpace = CGColorSpace.CreateDeviceRGB(); var bitmapContext = new CGBitmapContext(data, width, height, 8, width * 4, colorSpace, CGBitmapFlags.PremultipliedLast); bitmapContext.DrawImage(new RectangleF(0, 0, width, height), cgImage); bitmapContext.Dispose(); colorSpace.Dispose(); return(new Tuple <Microsoft.Xna.Framework.Point, byte[]>(new Microsoft.Xna.Framework.Point((int)width, (int)height), data)); } }
public IUGContext CreateDrawingSession() { var bpp = 8; var width = (nint)(Scale * Width + .5F); var height = (nint)(Scale * Height + .5F); var stride = 4 * width; var canvasRect = new CGRect(0F, 0F, Width, Height); using (var colorSpace = CGColorSpace.CreateSrgb()) { var context = new CGBitmapContext(null, width, height, bpp, stride, colorSpace, CGImageAlphaInfo.PremultipliedFirst); context.ScaleCTM(Scale, Scale); return(new UGContext(context, canvasRect, Scale, () => { _native = context.ToImage(); context.Dispose(); context = null; })); } }
public static void TexImage2D(Stream data, out int width, out int height) { data.Position = 0; var nsData = NSData.FromStream(data); var image = UIImage.LoadFromData(nsData); if (image == null) throw new Exception ("could not load image data"); width = (int)image.CGImage.Width; height = (int)image.CGImage.Height; var colorSpace = CGColorSpace.CreateDeviceRGB(); var imageData = new byte[height * width * 4]; var context = new CGBitmapContext (imageData, width, height, 8, 4 * width, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrder32Big); colorSpace.Dispose(); context.ClearRect(new CGRect(0, 0, width, height)); context.DrawImage(new CGRect(0, 0, width, height), image.CGImage); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, imageData); context.Dispose(); }
public NSImage Render(BitMatrix matrix, BarcodeFormat format, string content, EncodingOptions options) { var context = new CGBitmapContext(null, matrix.Width, matrix.Height, 8, 0, CGColorSpace.CreateGenericGray(), CGBitmapFlags.None); var black = new CGColor(0f, 0f, 0f); var white = new CGColor(1.0f, 1.0f, 1.0f); for (int x = 0; x < matrix.Width; x++) { for (int y = 0; y < matrix.Height; y++) { context.SetFillColor(matrix[x, y] ? black : white); context.FillRect(new CGRect(x, y, 1, 1)); } } var img = new NSImage(context.ToImage(), new CGSize(matrix.Width, matrix.Height)); context.Dispose(); return(img); }
public static NSImage ScaleImage(this NSImage target, CGSize size, bool disposeOriginal = false) { CGBitmapContext context; var width = (int)size.Width; var height = (int)size.Height; try { var colorspace = CGColorSpace.CreateDeviceRGB(); context = new CGBitmapContext(IntPtr.Zero, width, height, 8, 4 * width, colorspace, CGBitmapFlags.PremultipliedFirst); context.SetStrokeColorSpace(colorspace); context.SetFillColorSpace(colorspace); } catch (Exception exc) { throw new Exception($"Unable to allocate memory to scale the image to the size {size.Width},{size.Height}.", exc); } try { context.DrawImage(new CGRect(new CGPoint(0, 0), size), target.CGImage); var cgImage = context.ToImage(); var downsizedImage = new NSImage(cgImage, size); return(downsizedImage); } finally { context.Dispose(); if (disposeOriginal) { target?.Dispose(); } } }
private static Texture2D PlatformFromStream(GraphicsDevice graphicsDevice, CGImage cgImage) { var width = cgImage.Width; var height = cgImage.Height; var data = new byte[width * height * 4]; var colorSpace = CGColorSpace.CreateDeviceRGB(); var bitmapContext = new CGBitmapContext(data, width, height, 8, width * 4, colorSpace, CGBitmapFlags.PremultipliedLast); bitmapContext.DrawImage(new RectangleF(0, 0, width, height), cgImage); bitmapContext.Dispose(); colorSpace.Dispose(); Texture2D texture = null; Threading.BlockOnUIThread(() => { texture = new Texture2D(graphicsDevice, (int)width, (int)height, false, SurfaceFormat.Color); texture.SetData(data); }); return(texture); }
public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream) { //todo: partial classes would be cleaner #if IPHONE || MONOMAC #if IPHONE using (var uiImage = UIImage.LoadFromData(NSData.FromStream(stream))) #elif MONOMAC using (var nsImage = NSImage.FromStream (stream)) #endif { #if IPHONE var cgImage = uiImage.CGImage; #elif MONOMAC var cgImage = nsImage.AsCGImage (RectangleF.Empty, null, null); #endif var width = cgImage.Width; var height = cgImage.Height; var data = new byte[width * height * 4]; var colorSpace = CGColorSpace.CreateDeviceRGB(); var bitmapContext = new CGBitmapContext(data, width, height, 8, width * 4, colorSpace, CGBitmapFlags.PremultipliedLast); bitmapContext.DrawImage(new RectangleF(0, 0, width, height), cgImage); bitmapContext.Dispose(); colorSpace.Dispose(); Texture2D texture = null; Threading.BlockOnUIThread(() => { texture = new Texture2D(graphicsDevice, width, height, false, SurfaceFormat.Color); texture.SetData(data); }); return texture; } #elif ANDROID // Work-around for "The program 'Mono' has exited with code 255 (0xff)." // Based on http://stackoverflow.com/questions/7535503/mono-for-android-exit-code-255-on-bitmapfactory-decodestream //Bitmap image = BitmapFactory.DecodeStream(stream); Bitmap image = null; using (MemoryStream memStream = new MemoryStream()) { stream.CopyTo(memStream); image = BitmapFactory.DecodeByteArray(memStream.GetBuffer(), 0, (int)memStream.Length); } var width = image.Width; var height = image.Height; int[] pixels = new int[width * height]; if ((width != image.Width) || (height != image.Height)) { Bitmap imagePadded = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888); Canvas canvas = new Canvas(imagePadded); canvas.DrawARGB(0, 0, 0, 0); canvas.DrawBitmap(image, 0, 0, null); imagePadded.GetPixels(pixels, 0, width, 0, 0, width, height); } else { image.GetPixels(pixels, 0, width, 0, 0, width, height); } // Convert from ARGB to ABGR for (int i = 0; i < width * height; ++i) { uint pixel = (uint)pixels[i]; pixels[i] = (int)((pixel & 0xFF00FF00) | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16)); } Texture2D texture = null; Threading.BlockOnUIThread(() => { texture = new Texture2D(graphicsDevice, width, height, false, SurfaceFormat.Color); texture.SetData<int>(pixels); }); return texture; #elif WINRT // For reference this implementation was ultimately found through this post: // http://stackoverflow.com/questions/9602102/loading-textures-with-sharpdx-in-metro Texture2D toReturn = null; SharpDX.WIC.BitmapDecoder decoder; using(var bitmap = LoadBitmap(stream, out decoder)) using (decoder) { SharpDX.Direct3D11.Texture2D sharpDxTexture = CreateTex2DFromBitmap(bitmap, graphicsDevice); toReturn = new Texture2D(graphicsDevice, bitmap.Size.Width, bitmap.Size.Height); toReturn._texture = sharpDxTexture; } return toReturn; #elif DIRECTX throw new NotImplementedException(); #elif PSS return new Texture2D(graphicsDevice, stream); #else using (Bitmap image = (Bitmap)Bitmap.FromStream(stream)) { // Fix up the Image to match the expected format image.RGBToBGR(); var data = new byte[image.Width * image.Height * 4]; BitmapData bitmapData = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); if (bitmapData.Stride != image.Width * 4) throw new NotImplementedException(); Marshal.Copy(bitmapData.Scan0, data, 0, data.Length); image.UnlockBits(bitmapData); Texture2D texture = null; texture = new Texture2D(graphicsDevice, image.Width, image.Height); texture.SetData(data); return texture; } #endif }
public static UIImage AddImageReflection(UIImage image, float reflectionFraction) { int reflectionHeight = (int)(image.Size.Height * reflectionFraction); // Create a 2 bit CGImage containing a gradient that will be used for masking the // main view content to create the 'fade' of the reflection. The CGImageCreateWithMask // function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient // gradient is always black and white and the mask must be in the gray colorspace var colorSpace = CGColorSpace.CreateDeviceGray(); // Creat the bitmap context var gradientBitmapContext = new CGBitmapContext(IntPtr.Zero, 1, reflectionHeight, 8, 0, colorSpace, CGImageAlphaInfo.None); // define the start and end grayscale values (with the alpha, even though // our bitmap context doesn't support alpha the gradien requires it) float [] colors = { 0, 1, 1, 1 }; // Create the CGGradient and then release the gray color space var grayScaleGradient = new CGGradient(colorSpace, colors, null); colorSpace.Dispose(); // create the start and end points for the gradient vector (straight down) var gradientStartPoint = new PointF(0, reflectionHeight); var gradientEndPoint = PointF.Empty; // draw the gradient into the gray bitmap context gradientBitmapContext.DrawLinearGradient(grayScaleGradient, gradientStartPoint, gradientEndPoint, CGGradientDrawingOptions.DrawsAfterEndLocation); grayScaleGradient.Dispose(); // Add a black fill with 50% opactiy gradientBitmapContext.SetGrayFillColor(0, 0.5f); gradientBitmapContext.FillRect(new RectangleF(0, 0, 1, reflectionHeight)); // conver the context into a CGImage and release the context var gradientImageMask = gradientBitmapContext.ToImage(); gradientBitmapContext.Dispose(); // create an image by masking the bitmap of the mainView content with the gradient view // then release the pre-masked content bitmap and the gradient bitmap var reflectionImage = image.CGImage.WithMask(gradientImageMask); gradientImageMask.Dispose(); var size = new SizeF(image.Size.Width, image.Size.Height + reflectionHeight); UIGraphics.BeginImageContext(size); image.Draw(PointF.Empty); var context = UIGraphics.GetCurrentContext(); context.DrawImage(new RectangleF(0, image.Size.Height, image.Size.Width, reflectionHeight), reflectionImage); var result = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); reflectionImage.Dispose(); return(result); }
private void InitWithCGImage(CGImage image) { int width, height; CGBitmapContext bitmap = null; bool hasAlpha; CGImageAlphaInfo alphaInfo; CGColorSpace colorSpace; int bitsPerComponent, bytesPerRow; CGBitmapFlags bitmapInfo; bool premultiplied = false; int bitsPerPixel = 0; if (image == null) { throw new ArgumentException (" image is invalid! " ); } alphaInfo = image.AlphaInfo; hasAlpha = ((alphaInfo == CGImageAlphaInfo.PremultipliedLast) || (alphaInfo == CGImageAlphaInfo.PremultipliedFirst) || (alphaInfo == CGImageAlphaInfo.Last) || (alphaInfo == CGImageAlphaInfo.First) ? true : false); imageSize.Width = (int)image.Width; imageSize.Height = (int)image.Height; width = (int)image.Width; height = (int)image.Height; // Not sure yet if we need to keep the original image information // before we change it internally. TODO look at what windows does // and follow that. bitmapInfo = image.BitmapInfo; bitsPerComponent = (int)image.BitsPerComponent; bitsPerPixel = (int)image.BitsPerPixel; bytesPerRow = width * bitsPerPixel/bitsPerComponent; int size = bytesPerRow * height; colorSpace = image.ColorSpace; // Right now internally we represent the images all the same // I left the call here just in case we find that this is not // possible. Read the comments for non alpha images. if(colorSpace != null) { if( hasAlpha ) { premultiplied = true; colorSpace = CGColorSpace.CreateDeviceRGB (); bitsPerComponent = 8; bitsPerPixel = 32; bitmapInfo = CGBitmapFlags.PremultipliedLast; } else { // even for images without alpha we will internally // represent them as RGB with alpha. There were problems // if we do not do it this way and creating a bitmap context. // The images were not drawing correctly and tearing. Also // creating a Graphics to draw on was a nightmare. This // should probably be looked into or maybe it is ok and we // can continue representing internally with this representation premultiplied = true; colorSpace = CGColorSpace.CreateDeviceRGB (); bitsPerComponent = 8; bitsPerPixel = 32; bitmapInfo = CGBitmapFlags.NoneSkipLast; } } else { premultiplied = true; colorSpace = CGColorSpace.CreateDeviceRGB (); bitsPerComponent = 8; bitsPerPixel = 32; bitmapInfo = CGBitmapFlags.NoneSkipLast; } bytesPerRow = width * bitsPerPixel/bitsPerComponent; size = bytesPerRow * height; bitmapBlock = Marshal.AllocHGlobal (size); bitmap = new CGBitmapContext (bitmapBlock, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); bitmap.ClearRect (new CGRect (0,0,width,height)); // We need to flip the Y axis to go from right handed to lefted handed coordinate system var transform = new CGAffineTransform(1, 0, 0, -1, 0, image.Height); bitmap.ConcatCTM(transform); bitmap.DrawImage (new CGRect (0, 0, image.Width, image.Height), image); var provider = new CGDataProvider (bitmapBlock, size, true); NativeCGImage = new CGImage (width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, bitmapInfo, provider, null, true, image.RenderingIntent); colorSpace.Dispose(); bitmap.Dispose(); }
public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream) { //todo: partial classes would be cleaner #if IOS || MONOMAC #if IOS using (var uiImage = UIImage.LoadFromData(NSData.FromStream(stream))) #elif MONOMAC using (var nsImage = NSImage.FromStream (stream)) #endif { #if IOS var cgImage = uiImage.CGImage; #elif MONOMAC var rectangle = RectangleF.Empty; var cgImage = nsImage.AsCGImage (ref rectangle, null, null); #endif var width = cgImage.Width; var height = cgImage.Height; var data = new byte[width * height * 4]; var colorSpace = CGColorSpace.CreateDeviceRGB(); var bitmapContext = new CGBitmapContext(data, width, height, 8, width * 4, colorSpace, CGBitmapFlags.PremultipliedLast); bitmapContext.DrawImage(new RectangleF(0, 0, width, height), cgImage); bitmapContext.Dispose(); colorSpace.Dispose(); Texture2D texture = null; Threading.BlockOnUIThread(() => { texture = new Texture2D(graphicsDevice, width, height, false, SurfaceFormat.Color); texture.SetData(data); }); return texture; } #elif ANDROID using (Bitmap image = BitmapFactory.DecodeStream(stream, null, new BitmapFactory.Options { InScaled = false, InDither = false, InJustDecodeBounds = false, InPurgeable = true, InInputShareable = true, })) { var width = image.Width; var height = image.Height; int[] pixels = new int[width * height]; if ((width != image.Width) || (height != image.Height)) { using (Bitmap imagePadded = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888)) { Canvas canvas = new Canvas(imagePadded); canvas.DrawARGB(0, 0, 0, 0); canvas.DrawBitmap(image, 0, 0, null); imagePadded.GetPixels(pixels, 0, width, 0, 0, width, height); imagePadded.Recycle(); } } else { image.GetPixels(pixels, 0, width, 0, 0, width, height); } image.Recycle(); // Convert from ARGB to ABGR for (int i = 0; i < width * height; ++i) { uint pixel = (uint)pixels[i]; pixels[i] = (int)((pixel & 0xFF00FF00) | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16)); } Texture2D texture = null; Threading.BlockOnUIThread(() => { texture = new Texture2D(graphicsDevice, width, height, false, SurfaceFormat.Color); texture.SetData<int>(pixels); }); return texture; } #elif WINDOWS_PHONE throw new NotImplementedException(); #elif WINDOWS_STOREAPP || DIRECTX // For reference this implementation was ultimately found through this post: // http://stackoverflow.com/questions/9602102/loading-textures-with-sharpdx-in-metro Texture2D toReturn = null; SharpDX.WIC.BitmapDecoder decoder; using(var bitmap = LoadBitmap(stream, out decoder)) using (decoder) { SharpDX.Direct3D11.Texture2D sharpDxTexture = CreateTex2DFromBitmap(bitmap, graphicsDevice); toReturn = new Texture2D(graphicsDevice, bitmap.Size.Width, bitmap.Size.Height); toReturn._texture = sharpDxTexture; } return toReturn; #elif PSM return new Texture2D(graphicsDevice, stream); #else using (Bitmap image = (Bitmap)Bitmap.FromStream(stream)) { // Fix up the Image to match the expected format image.RGBToBGR(); var data = new byte[image.Width * image.Height * 4]; BitmapData bitmapData = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); if (bitmapData.Stride != image.Width * 4) throw new NotImplementedException(); Marshal.Copy(bitmapData.Scan0, data, 0, data.Length); image.UnlockBits(bitmapData); Texture2D texture = null; texture = new Texture2D(graphicsDevice, image.Width, image.Height); texture.SetData(data); return texture; } #endif }
internal new void RotateFlip(RotateFlipType rotateFlipType) { CGAffineTransform rotateFlip = CGAffineTransform.MakeIdentity(); int width, height; width = (int)NativeCGImage.Width; height = (int)NativeCGImage.Height; switch (rotateFlipType) { // case RotateFlipType.RotateNoneFlipNone: // //case RotateFlipType.Rotate180FlipXY: // rotateFlip = GeomUtilities.CreateRotateFlipTransform (b.Width, b.Height, 0, false, false); // break; case RotateFlipType.Rotate90FlipNone: //case RotateFlipType.Rotate270FlipXY: rotateFlip = GeomUtilities.CreateRotateFlipTransform(ref width, ref height, 90, false, false); break; case RotateFlipType.Rotate180FlipNone: //case RotateFlipType.RotateNoneFlipXY: rotateFlip = GeomUtilities.CreateRotateFlipTransform(ref width, ref height, 0, true, true); break; case RotateFlipType.Rotate270FlipNone: //case RotateFlipType.Rotate90FlipXY: rotateFlip = GeomUtilities.CreateRotateFlipTransform(ref width, ref height, 270, false, false); break; case RotateFlipType.RotateNoneFlipX: //case RotateFlipType.Rotate180FlipY: rotateFlip = GeomUtilities.CreateRotateFlipTransform(ref width, ref height, 0, true, false); break; case RotateFlipType.Rotate90FlipX: //case RotateFlipType.Rotate270FlipY: rotateFlip = GeomUtilities.CreateRotateFlipTransform(ref width, ref height, 90, true, false); break; case RotateFlipType.Rotate180FlipX: //case RotateFlipType.RotateNoneFlipY: rotateFlip = GeomUtilities.CreateRotateFlipTransform(ref width, ref height, 0, false, true); break; case RotateFlipType.Rotate270FlipX: //case RotateFlipType.Rotate90FlipY: rotateFlip = GeomUtilities.CreateRotateFlipTransform(ref width, ref height, 270, true, false); break; } var bytesPerRow = (width * (int)NativeCGImage.BitsPerPixel + 7) / 8; var newBitmapBlock = Marshal.AllocHGlobal(height * bytesPerRow); var newBitmapContext = new CGBitmapContext(newBitmapBlock, width, height, NativeCGImage.BitsPerComponent, bytesPerRow, NativeCGImage.ColorSpace, NativeCGImage.AlphaInfo); newBitmapContext.ConcatCTM(rotateFlip); newBitmapContext.DrawImage(new CGRect(0, 0, NativeCGImage.Width, NativeCGImage.Height), NativeCGImage); newBitmapContext.Flush(); // If the width or height is not the seme we need to switch the dpiHeight and dpiWidth // We should be able to get around this with set resolution later. if (NativeCGImage.Width != width || NativeCGImage.Height != height) { var temp = dpiWidth; dpiHeight = dpiWidth; dpiWidth = temp; } physicalDimension.Width = (float)width; physicalDimension.Height = (float)height; physicalSize = new SizeF(physicalDimension.Width, physicalDimension.Height); physicalSize.Width *= ConversionHelpers.MS_DPI / dpiWidth; physicalSize.Height *= ConversionHelpers.MS_DPI / dpiHeight; // In windows the RawFormat is changed to MemoryBmp to show that the image has changed. rawFormat = ImageFormat.MemoryBmp; // Set our transform for this image for the new height imageTransform = new CGAffineTransform(1, 0, 0, -1, 0, height); // bitmapBlock is owned by dataProvider and freed implicitly if (dataProvider != null) { dataProvider.Dispose(); } if (cachedContext != null) { cachedContext.Dispose(); } NativeCGImage.Dispose(); this.bitmapBlock = newBitmapBlock; this.dataProvider = new CGDataProvider(bitmapBlock, height * bytesPerRow); this.NativeCGImage = newBitmapContext.ToImage(); this.cachedContext = newBitmapContext; this.imageSource = null; // update the cached size imageSize.Width = this.Width; imageSize.Height = this.Height; }
protected override void Dispose(bool disposing) { renderContext.Dispose(); base.Dispose(disposing); }
/// <summary> /// converts an image to an ascii web page /// </summary> /// <param name="img">image to convert</param> /// <param name="fileStream">opened file to write HTML</param> /// <param name="imgBlockSize"> /// used to determine the width in pixels of one ascii character /// which is then used to determine the block size in pixels /// of one ascii character /// </param> /// <param name="fontSize"> /// fixed width font size in pixels /// <remarks>5 pixels seems to be a good value</remarks> /// </param> /// <param name="quick"> /// <remarks> /// quick brightness calculation is only done on first row of pixels in a block /// </remarks> /// </param> /// <param name="colour">true to generate a colour ascii image</param> /// <param name="monitor"> /// optional callback to monitor progress, <seealso cref="IAsciiArtProgress"/> /// <remarks>pass in null to not monitor progress</remarks> /// </param> /// <returns></returns> public static void ConvertImage(UIImage img, StreamWriter fileStream, int imgBlockSize, int fontSize, bool quick, bool colour, ICancellableProgressCallback monitor) { const string WebPage1 = "<html>" + "<body>" + "<pre>" + "<span style=\"font-size: {0}px;font-family: monospace;\">"; fileStream.Write(WebPage1, fontSize); var buffer = Marshal.AllocHGlobal((int)(img.Size.Width * img.Size.Height * 4)); var colorSpace = CGColorSpace.CreateDeviceRGB(); var context = new CGBitmapContext(buffer, (int)img.Size.Width, (int)img.Size.Height, 8, 4 * (int)img.Size.Width, colorSpace, CGImageAlphaInfo.NoneSkipFirst); try { context.InterpolationQuality = CGInterpolationQuality.None; context.DrawImage(new Rectangle(0, 0, (int)img.Size.Width, (int)img.Size.Height), img.CGImage); unsafe { var bufPtr = (byte *)((void *)buffer); var pixWidth = imgBlockSize; var pixHeight = pixWidth * 2; var pixSeg = pixWidth * pixHeight; var numHeightIter = img.Size.Height / pixHeight; var numWidthIter = img.Size.Width / pixWidth; var percentIter = (int)(numHeightIter * numWidthIter / 100) + 1; var currIter = 0; for (var h = 0; h < numHeightIter; h++, currIter++) { // segment height var startY = (h * pixHeight); // segment width for (var w = 0; w < numWidthIter; w++, currIter++) { if (monitor.Cancel) { return; } if ((currIter % percentIter) == 0) { NSRunLoop.Current.RunUntil(DateTime.Now.AddMilliseconds(10)); monitor.Progress((int)(currIter / percentIter)); } var startX = (w * pixWidth); var allBrightness = 0f; var allAlpha = 0f; var allRed = 0f; var allGreen = 0f; var allBlue = 0f; if (quick) { // each pix of this segment for (var y = 0; y < pixWidth; y++) { var cY = y + startY; var cX = 0 + startX; try { if (cX < img.Size.Width) { int offset = (int)(4 * (img.Size.Width * cY + cX)); float alpha = (float)bufPtr[offset] / 255f; float red = (float)bufPtr[offset + 1] / 255f; float green = (float)bufPtr[offset + 2] / 255f; float blue = (float)bufPtr[offset + 3] / 255f; allAlpha += alpha; allRed += red; allGreen += green; allBlue += blue; allBrightness += RGBtoBrightness(red, green, blue); } } catch { allBrightness += 0.5f; } } } else { // each pix of this segment for (var y = 0; y < pixWidth; y++) { for (var x = 0; x < pixHeight; x++) { var cY = y + startY; var cX = x + startX; try { if (cX < img.Size.Width) { int offset = (int)(4 * (img.Size.Width * cY + cX)); float alpha = (float)bufPtr[offset] / 255f; float red = (float)bufPtr[offset + 1] / 255f; float green = (float)bufPtr[offset + 2] / 255f; float blue = (float)bufPtr[offset + 3] / 255f; allAlpha += alpha; allRed += red; allGreen += green; allBlue += blue; allBrightness += RGBtoBrightness(red, green, blue); } } catch { allBrightness += 0.5f; } } } } var avgBrt = (allBrightness / pixSeg) * 100f; string asciiChar; if (avgBrt < 10) { asciiChar = "#"; } else if (avgBrt < 17) { asciiChar = "@"; } else if (avgBrt < 24) { asciiChar = "&"; } else if (avgBrt < 31) { asciiChar = "$"; } else if (avgBrt < 38) { asciiChar = "%"; } else if (avgBrt < 45) { asciiChar = "|"; } else if (avgBrt < 52) { asciiChar = "!"; } else if (avgBrt < 59) { asciiChar = ";"; } else if (avgBrt < 66) { asciiChar = ":"; } else if (avgBrt < 73) { asciiChar = "'"; } else if (avgBrt < 80) { asciiChar = "`"; } else if (avgBrt < 87) { asciiChar = "."; } else { asciiChar = " "; } if (colour) { const string ColourCharElement = "<code style=\"color:{0}\">{1}</code>"; var avgRed = (allRed / pixSeg); var avgGreen = (allGreen / pixSeg); var avgBlue = (allBlue / pixSeg); var clrHex = string.Format("#{0:x}{1:x}{2:x}", (int)(avgRed * 255), (int)(avgGreen * 255), (int)(avgBlue * 255)); var asciiStr = string.Format(ColourCharElement, clrHex, asciiChar); fileStream.Write(asciiStr); } else { fileStream.Write(asciiChar); } } fileStream.Write("\n"); } } } finally { context.Dispose(); colorSpace.Dispose(); Marshal.FreeHGlobal(buffer); } const string WebPage3 = "</span>" + "</pre>" + "</body>" + "</html>"; fileStream.Write(WebPage3); }
public UIImage ProcessedImage() { nfloat scale = UIScreen.MainScreen.Scale; CGImage imageRef = _originalImage.CGImage; if (imageRef == null) return null; var bytesPerRow = 0; var bitsPerComponent = imageRef.BitsPerComponent; CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB(); var bitmapInfo = imageRef.BitmapInfo; CGBitmapContext context = new CGBitmapContext(null, (nint)(_targetSize.Width * scale), (nint)(_targetSize.Height * scale), bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); colorSpace.Dispose(); if (context == null) { imageRef.Dispose(); return null; } CGRect targetFrame = LocalCropFrame(); context.InterpolationQuality = CGInterpolationQuality.High; context.SetBlendMode(CGBlendMode.Copy); context.DrawImage(targetFrame, imageRef); var contextImage = context.ToImage(); UIImage finalImage = null; context.Dispose(); if (contextImage != null) { finalImage = UIImage.FromImage(contextImage, scale, UIImageOrientation.Up); contextImage.Dispose(); } imageRef.Dispose(); return finalImage; }
public Texture2D(UIImage uiImage) { if (uiImage == null) { throw new ArgumentNullException("uiImage"); } CGImage image = uiImage.CGImage; if (image == null) { throw new InvalidOperationException("Attempted to create a Texture2D from UIImage, but resulting CGImage is null"); } CGImageAlphaInfo info = image.AlphaInfo; bool hasAlpha = info == CGImageAlphaInfo.PremultipliedLast || info == CGImageAlphaInfo.PremultipliedFirst || info == CGImageAlphaInfo.Last || info == CGImageAlphaInfo.First; int bpp = image.BitsPerComponent; Texture2DPixelFormat pixelFormat; if (image.ColorSpace != null) { if (hasAlpha || bpp >= 8) { pixelFormat = Texture2DPixelFormat.Default; } else { pixelFormat = Texture2DPixelFormat.RGB565; } } else { pixelFormat = Texture2DPixelFormat.A8; } int width = image.Width; if (width != 1 && (width & (width - 1)) != 0) { int i = 1; while (i < width) { i *= 2; } width = i; } int height = image.Height; if (height != 1 && (height & (height - 1)) != 0) { int i = 1; while (i < height) { i *= 2; } height = i; } if (width > MaxTextureSize || height > MaxTextureSize) { throw new InvalidOperationException("Image is too large. Width or height larger than MaxTextureSize"); } CGColorSpace colorSpace = null; CGContext context; byte[] data; unsafe { // all formats require w*h*4, except A8 requires just w*h int dataSize = width * height * 4; if (pixelFormat == Texture2DPixelFormat.A8) { dataSize = width * height; } data = new byte[dataSize]; fixed (byte* dp = data) { switch (pixelFormat) { case Texture2DPixelFormat.RGBA8888: case Texture2DPixelFormat.RGBA4444: case Texture2DPixelFormat.RGB5A1: colorSpace = CGColorSpace.CreateDeviceRGB(); context = new CGBitmapContext((IntPtr)dp, (int)width, (int)height, 8, 4 * (int)width, colorSpace, CGImageAlphaInfo.PremultipliedLast); break; case Texture2DPixelFormat.RGB565: colorSpace = CGColorSpace.CreateDeviceRGB(); context = new CGBitmapContext((IntPtr)dp, (int)width, (int)height, 8, 4 * (int)width, colorSpace, CGImageAlphaInfo.NoneSkipLast); break; case Texture2DPixelFormat.A8: context = new CGBitmapContext((IntPtr)dp, (int)width, (int)height, 8, (int)width, null, CGImageAlphaInfo.Only); break; default: throw new InvalidEnumArgumentException("pixelFormat", (int)pixelFormat, typeof(Texture2DPixelFormat)); } if (colorSpace != null) { colorSpace.Dispose(); } context.ClearRect(new RectangleF(0, 0, width, height)); context.TranslateCTM(0, height - image.Height); // why is this here? make an identity transform, then immediately not use it? Need to look into this CGAffineTransform transform = CGAffineTransform.MakeIdentity(); if (!transform.IsIdentity) { context.ConcatCTM(transform); } context.DrawImage(new RectangleF(0, 0, image.Width, image.Height), image); } } if (pixelFormat == Texture2DPixelFormat.RGB565) { //Convert "RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB" byte[] tempData = new byte[height * width * 2]; unsafe { fixed (byte* inPixel32b = data) { uint* inPixel32 = (uint*)inPixel32b; fixed (byte* outPixel16b = tempData) { ushort* outPixel16 = (ushort*)outPixel16b; for (int i = 0; i < width * height; ++i,++inPixel32) { uint tempInt32 = ((((*inPixel32 >> 0) & 0xff) >> 3) << 11) | ((((*inPixel32 >> 8) & 0xff) >> 2) << 5) | ((((*inPixel32 >> 16) & 0xff) >> 3) << 0); *outPixel16++ = (ushort)tempInt32; } } } } data = tempData; } else if (pixelFormat == Texture2DPixelFormat.RGBA4444) { //Convert "RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA" byte[] tempData = new byte[height * width * 2]; unsafe { fixed (byte* inPixel32b = data) { uint* inPixel32 = (uint*)inPixel32b; fixed (byte* outPixel16b = tempData) { ushort* outPixel16 = (ushort*)outPixel16b; for (int i = 0; i < width * height; ++i,++inPixel32) { uint tempInt32 = ((((*inPixel32 >> 0) & 0xff) >> 4) << 12) | ((((*inPixel32 >> 8) & 0xff) >> 4) << 8) | ((((*inPixel32 >> 16) & 0xff) >> 4) << 4) | ((((*inPixel32 >> 24) & 0xff) >> 4) << 0); *outPixel16++ = (ushort)tempInt32; } } } } data = tempData; } else if (pixelFormat == Texture2DPixelFormat.RGB5A1) { //Convert "RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA" byte[] tempData = new byte[height * width * 2]; unsafe { fixed (byte* inPixel32b = data) { uint* inPixel32 = (uint*)inPixel32b; fixed (byte* outPixel16b = tempData) { ushort* outPixel16 = (ushort*)outPixel16b; for (int i = 0; i < width * height; ++i,++inPixel32) { uint tempInt32 = ((((*inPixel32 >> 0) & 0xff) >> 3) << 11) | ((((*inPixel32 >> 8) & 0xff) >> 3) << 6) | ((((*inPixel32 >> 16) & 0xff) >> 3) << 1) | ((((*inPixel32 >> 24) & 0xff) >> 7) << 0); *outPixel16++ = (ushort)tempInt32; } } } } data = tempData; } InitWithData(data, pixelFormat, width, height, new SizeF(image.Width, image.Height)); HasPremultipliedAlpha = info == CGImageAlphaInfo.PremultipliedLast || info == CGImageAlphaInfo.PremultipliedFirst; context.Dispose(); }
public void SetOriginalImage(UIImage originalImage, CGRect cropFrame) { LoadIndicator.StartAnimating(); InvokeOnMainThread(() => { CGImage imageRef = originalImage.CGImage; UIImageOrientation imageOrientation = originalImage.Orientation; if (imageRef == null) return; var bytesPerRow = 0; var width = imageRef.Width; var height = imageRef.Height; var bitsPerComponent = imageRef.BitsPerComponent; CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB(); CGBitmapFlags bitmapInfo = imageRef.BitmapInfo; switch (imageOrientation) { case UIImageOrientation.RightMirrored: case UIImageOrientation.LeftMirrored: case UIImageOrientation.Right: case UIImageOrientation.Left: width = imageRef.Height; height = imageRef.Width; break; default: break; } CGSize imageSize = new CGSize(width, height); CGBitmapContext context = new CGBitmapContext(null, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); colorSpace.Dispose(); if (context == null) { imageRef.Dispose(); return; } switch (imageOrientation) { case UIImageOrientation.RightMirrored: case UIImageOrientation.Right: context.TranslateCTM(imageSize.Width / 2, imageSize.Height / 2); context.RotateCTM(-((nfloat)Math.PI / 2)); context.TranslateCTM(-imageSize.Height / 2, -imageSize.Width / 2); break; case UIImageOrientation.LeftMirrored: case UIImageOrientation.Left: context.TranslateCTM(imageSize.Width / 2, imageSize.Height / 2); context.RotateCTM((nfloat)(Math.PI / 2)); context.TranslateCTM(-imageSize.Height / 2, -imageSize.Width / 2); break; case UIImageOrientation.Down: case UIImageOrientation.DownMirrored: context.TranslateCTM(imageSize.Width / 2, imageSize.Height / 2); context.RotateCTM((nfloat)Math.PI); context.TranslateCTM(-imageSize.Width / 2, -imageSize.Height / 2); break; default: break; } context.InterpolationQuality = CGInterpolationQuality.High; context.SetBlendMode(CGBlendMode.Copy); context.DrawImage(new CGRect(0, 0, imageRef.Width, imageRef.Height), imageRef); CGImage contextImage = context.ToImage(); context.Dispose(); if (contextImage != null) { _originalImage = UIImage.FromImage(contextImage, originalImage.CurrentScale, UIImageOrientation.Up); contextImage.Dispose(); } imageRef.Dispose(); BeginInvokeOnMainThread(() => { CGSize convertedImageSize = new CGSize(_originalImage.Size.Width / _cropSizeRatio, _originalImage.Size.Height / _cropSizeRatio); ImageView.Alpha = 0; ImageView.Image = _originalImage; CGSize sampleImageSize = new CGSize(Math.Max(convertedImageSize.Width, ScrollView.Frame.Size.Width), Math.Max(convertedImageSize.Height, ScrollView.Frame.Size.Height)); ScrollView.MinimumZoomScale = 1; ScrollView.MaximumZoomScale = 1; ScrollView.ZoomScale = 1; ImageView.Frame = new CGRect(0, 0, convertedImageSize.Width, convertedImageSize.Height); nfloat zoomScale = 1; if (convertedImageSize.Width < convertedImageSize.Height) { zoomScale = (ScrollView.Frame.Size.Width / convertedImageSize.Width); } else { zoomScale = (ScrollView.Frame.Size.Height / convertedImageSize.Height); } ScrollView.ContentSize = sampleImageSize; if (zoomScale < 1) { ScrollView.MinimumZoomScale = zoomScale; ScrollView.MaximumZoomScale = 1; ScrollView.ZoomScale = zoomScale; } else { ScrollView.MinimumZoomScale = zoomScale; ScrollView.MaximumZoomScale = zoomScale; ScrollView.ZoomScale = zoomScale; } ScrollView.ContentInset = UIEdgeInsets.Zero; ScrollView.ContentOffset = new CGPoint((ImageView.Frame.Size.Width - ScrollView.Frame.Size.Width) / 2, (ImageView.Frame.Size.Height - ScrollView.Frame.Size.Height) / 2); if (cropFrame.Size.Width > 0 && cropFrame.Size.Height > 0) { nfloat scale = UIScreen.MainScreen.Scale; nfloat newZoomScale = (_targetSize.Width * scale) / cropFrame.Size.Width; ScrollView.ZoomScale = newZoomScale; nfloat heightAdjustment = (_targetSize.Height / _cropSizeRatio) - ScrollView.ContentSize.Height; nfloat offsetY = cropFrame.Y + (heightAdjustment * _cropSizeRatio * scale); ScrollView.ContentOffset = new CGPoint(cropFrame.X / scale / _cropSizeRatio, (offsetY / scale / _cropSizeRatio) - heightAdjustment); } ScrollView.SetNeedsLayout(); UIView.Animate(0.3, () => { LoadIndicator.Alpha = 0; ImageView.Alpha = 1; }, () => { LoadIndicator.StopAnimating(); }); }); }); }
public void Dispose() { _context.Dispose(); _colorSpace.Dispose(); _handle.Free(); }
public static CGImage Scale (CGImage image, Rectangle drawRect, Size size) { var bytesPerRow = (size.Width * 4); var totalBytes = (bytesPerRow * size.Height); IntPtr bitmapData = IntPtr.Zero; CGBitmapContext context = null; CGImage outImage; try { bitmapData = Marshal.AllocHGlobal (totalBytes); if (bitmapData == IntPtr.Zero) { return null; } using (var colorSpace = CGColorSpace.CreateDeviceRGB ()) { context = new CGBitmapContext ( bitmapData, size.Width, size.Height, 8, bytesPerRow, colorSpace, CGImageAlphaInfo.NoneSkipFirst ); } if (context == null) return null; context.DrawImage (drawRect, image); outImage = context.ToImage (); } catch { return null; } finally { if (context != null) context.Dispose (); Marshal.FreeHGlobal (bitmapData); } return outImage; }
public override void Dispose() { _bitmapContext?.Dispose(); base.Dispose(); }
public Size GetCharData(char c,out UInt32[] cdata) { NSString str =new NSString(c.ToString()); var size=str.StringSize(font); UIGraphics.BeginImageContextWithOptions(size,false,1.0f); UIGraphics.GetCurrentContext().SetFillColor(1.0f,1.0f,1.0f,1.0f); str.DrawString(new System.Drawing.PointF(0,0),font); UIImage img =UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); // int width=(int)size.Width; int height=(int)size.Height; cdata=new UInt32[width*height]; var gdata=new byte[width*height*4]; var colorSpace = CGColorSpace.CreateDeviceRGB(); var gbmp = new CGBitmapContext(gdata, width, height, 8, width * 4, colorSpace, CGBitmapFlags.PremultipliedLast); //gbmp.ClearRect(new RectangleF(0,0,width,height)); gbmp.DrawImage(new System.Drawing.RectangleF(0,0,width,height),img.CGImage); gbmp.Dispose(); colorSpace.Dispose(); unsafe { fixed(byte* srcb = gdata) fixed (UInt32* dest=cdata) { UInt32* src=(UInt32*)srcb; for(int y=0;y<height;y++) { for(int x=0;x<width;x++) { dest[y*width+x]=src[y*width+x]; } } } } return new Size(width,height); }
static CGImage applyMosaic(int tileSize, List<Color> colorPalette, UIImage resizedImg, Bitmap bitmap) { // - Parameters int width = tileSize; // tile width int height = tileSize; // tile height int outWidth = (int)(resizedImg.Size.Width - (resizedImg.Size.Width % width)); // Round image size int outHeight = (int)(resizedImg.Size.Height - (resizedImg.Size.Height % height)); // -- Initialize buffer CGBitmapContext context = new CGBitmapContext (System.IntPtr.Zero, // data (int)outWidth, // width (int)outHeight, // height 8, // bitsPerComponent outWidth * 4, // bytesPerRow based on pixel width CGColorSpace.CreateDeviceRGB (), // colorSpace CGImageAlphaInfo.NoneSkipFirst); // bitmapInfo for (int yb = 0; yb < outHeight / height; yb++) { for (int xb = 0; xb < outWidth / width; xb++) { // -- Do the average colors on the source image for the // corresponding mosaic square int r_avg = 0; int g_avg = 0; int b_avg = 0; for (int y = yb * height; y < (yb * height) + height; y++) { for (int x = xb * width; x < (xb * width) + width; x++) { Color c = bitmap.GetPixel (x, y); // Retrieve color values of the source image r_avg += c.R; g_avg += c.G; b_avg += c.B; } } // Make average of R,G and B on filter size r_avg = r_avg / (width * height); g_avg = g_avg / (width * height); b_avg = b_avg / (width * height); // Find the nearest color in the palette Color mosaicColor = new Color (); double minDistance = int.MaxValue; foreach (Color c in colorPalette) { double distance = Math.Abs (Math.Pow (r_avg - c.R, 2) + Math.Pow (g_avg - c.G, 2) + Math.Pow (b_avg - c.B, 2)); if (distance < minDistance) { mosaicColor = c; minDistance = distance; } } // Apply mosaic for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { context.SetFillColor (new CGColor (mosaicColor.R / 255f, mosaicColor.G / 255f, mosaicColor.B / 255f)); context.FillRect (new RectangleF (xb * width, yb * height, width, height)); } } } } //-- image from buffer CGImage flippedImage = context.ToImage (); context.Dispose (); return flippedImage; }
public void DrawClock() { if (imageView.Image != null) { imageView.Image.Dispose(); } if (ctx != null) { ctx.Dispose(); } ctx = new CGBitmapContext(IntPtr.Zero, (int)imageView.Bounds.Width, (int)imageView.Bounds.Height, 8, 4 * (int)imageView.Bounds.Width, CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedFirst); GC.Collect(); CGColor red = new CGColor(1f, 0f, 0f, 1f); CGColor black = new CGColor(0f, 0f, 0f, 1f); DateTime now = DateTime.Now; int big_hand_width, small_hand_width, big_square_size, small_square_size; if (ipad) { big_hand_width = 16; small_hand_width = 10; big_square_size = 20; small_square_size = 10; } else { big_hand_width = 8; small_hand_width = 5; big_square_size = 10; small_square_size = 5; } float x, y; int r; int sXmax = (int)imageView.Bounds.Width; int sYmax = (int)imageView.Bounds.Width - big_square_size; int smax; if (sXmax <= sYmax) { smax = sXmax; } else { smax = sYmax; } int hand_max = (smax / 2) - 1; int sXcen = sXmax / 2; int sYcen = sYmax / 2; #region Draw circle for (r = 0; r < 60; r++) { x = ((float)Math.Cos(r * Math.PI / 180 * 6) * hand_max) + sXcen; y = ((float)Math.Sin(r * Math.PI / 180 * 6) * hand_max) + sYcen; switch (r) { case 0: case 5: case 10: case 15: case 20: case 25: case 30: case 35: case 40: case 45: case 50: case 55: ctx.SetFillColorWithColor(red); ctx.FillRect(new System.Drawing.RectangleF(y, x, big_square_size, big_square_size)); break; default: ctx.SetFillColorWithColor(black); ctx.FillRect(new System.Drawing.RectangleF(y, x, small_square_size, small_square_size)); break; } } #endregion #region Draw hour hand ctx.SetStrokeColorWithColor(black); float r_hour = (float)((30 * (now.Hour % 12) + now.Minute * 0.5) * (Math.PI / 180)); ctx.MoveTo(sXcen, sYcen); ctx.SetLineWidth(big_hand_width); ctx.AddLineToPoint((float)(Math.Sin(r_hour) * (3 * hand_max / 5) + sYcen), (float)(Math.Cos(r_hour) * (3 * hand_max / 5) + sXcen)); ctx.StrokePath(); #endregion #region Draw minute hand ctx.SetStrokeColorWithColor(black); float r_minute = (float)((6 * now.Minute) * (Math.PI / 180)); ctx.MoveTo(sXcen, sYcen); ctx.SetLineWidth(small_hand_width); ctx.AddLineToPoint((float)(Math.Sin(r_minute) * (hand_max - 5) + sYcen), (float)(Math.Cos(r_minute) * (hand_max - 5) + sXcen)); ctx.StrokePath(); #endregion #region Draw minute hand ctx.SetStrokeColorWithColor(red); float r_second = (float)((6 * now.Second) * (Math.PI / 180)); ctx.MoveTo(sXcen, sYcen); ctx.SetLineWidth(5); ctx.AddLineToPoint((float)(Math.Sin(r_second) * (hand_max - 5) + sYcen), (float)(Math.Cos(r_second) * (hand_max - 5) + sXcen)); ctx.StrokePath(); #endregion float aclockX, aclockY, digital_timeX, digital_timeY, font_size; if (ipad) { font_size = 32f; aclockX = imageView.Bounds.GetMaxX() / 2 - 80; aclockY = imageView.Bounds.GetMaxY() - 100; digital_timeX = imageView.Bounds.GetMaxX() / 2 - 70; digital_timeY = imageView.Bounds.GetMaxY() - 150; } else { font_size = 16f; aclockX = imageView.Bounds.GetMaxX() / 2 - 40; aclockY = imageView.Bounds.GetMaxY() - 50; digital_timeX = imageView.Bounds.GetMaxX() / 2 - 35; digital_timeY = imageView.Bounds.GetMaxY() - 100; } ctx.SetFillColorWithColor(black); ctx.SelectFont("American Typewriter", font_size, CGTextEncoding.MacRoman); ctx.SetTextDrawingMode(CGTextDrawingMode.Fill); ctx.ShowTextAtPoint(aclockX, aclockY, ".:ACLOCK:."); string digital_time; if (now.Second % 2 == 0) { digital_time = String.Format("{0}:{1}:{2}", now.Hour.ToString("00"), now.Minute.ToString("00"), now.Second.ToString("00")); } else { digital_time = String.Format("{0} {1} {2}", now.Hour.ToString("00"), now.Minute.ToString("00"), now.Second.ToString("00")); } ctx.SetFillColorWithColor(black); ctx.SelectFont("American Typewriter", font_size, CGTextEncoding.MacRoman); ctx.SetTextDrawingMode(CGTextDrawingMode.Fill); ctx.ShowTextAtPoint(digital_timeX, digital_timeY, digital_time); imageView.Image = UIImage.FromImage(ctx.ToImage()); ctx.Dispose(); }
private void InitWithCGImage(CGImage image, All filter) { int width, height, i; CGContext context = null; IntPtr data; CGColorSpace colorSpace; IntPtr tempData; bool hasAlpha; CGImageAlphaInfo info; CGAffineTransform transform; Size imageSize; SurfaceFormat pixelFormat; bool sizeToFit = false; if (image == null) { throw new ArgumentException(" NSImage is invalid! "); } info = image.AlphaInfo; hasAlpha = ((info == CGImageAlphaInfo.PremultipliedLast) || (info == CGImageAlphaInfo.PremultipliedFirst) || (info == CGImageAlphaInfo.Last) || (info == CGImageAlphaInfo.First) ? true : false); if (image.ColorSpace != null) { if (hasAlpha) { pixelFormat = SurfaceFormat.Rgba32; } else { pixelFormat = SurfaceFormat.Rgb32; } } else { pixelFormat = SurfaceFormat.Alpha8; } imageSize = new Size(image.Width, image.Height); transform = CGAffineTransform.MakeIdentity(); width = imageSize.Width; if ((width != 1) && ((width & (width - 1)) != 0)) { i = 1; while ((sizeToFit ? 2 * i : i) < width) { i *= 2; } width = i; } height = imageSize.Height; if ((height != 1) && ((height & (height - 1)) != 0)) { i = 1; while ((sizeToFit ? 2 * i : i) < height) { i *= 2; } height = i; } // TODO: kMaxTextureSize = 1024 while ((width > 1024) || (height > 1024)) { width /= 2; height /= 2; transform = CGAffineTransform.MakeScale(0.5f, 0.5f); imageSize.Width /= 2; imageSize.Height /= 2; } switch (pixelFormat) { case SurfaceFormat.Rgba32: colorSpace = CGColorSpace.CreateDeviceRGB(); data = Marshal.AllocHGlobal(height * width * 4); context = new CGBitmapContext(data, width, height, 8, 4 * width, colorSpace, CGImageAlphaInfo.PremultipliedLast); colorSpace.Dispose(); break; case SurfaceFormat.Rgb32: colorSpace = CGColorSpace.CreateDeviceRGB(); data = Marshal.AllocHGlobal(height * width * 4); context = new CGBitmapContext(data, width, height, 8, 4 * width, colorSpace, CGImageAlphaInfo.NoneSkipLast); colorSpace.Dispose(); break; case SurfaceFormat.Alpha8: data = Marshal.AllocHGlobal(height * width); context = new CGBitmapContext(data, width, height, 8, width, null, CGImageAlphaInfo.Only); break; default: throw new NotSupportedException("Invalid pixel format"); } context.ClearRect(new RectangleF(0, 0, width, height)); context.TranslateCTM(0, height - imageSize.Height); if (!transform.IsIdentity) { context.ConcatCTM(transform); } context.DrawImage(new RectangleF(0, 0, image.Width, image.Height), image); //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB" if (pixelFormat == SurfaceFormat.Rgb32) { tempData = Marshal.AllocHGlobal(height * width * 2); int d32; short d16; int inPixel32Count = 0, outPixel16Count = 0; for (i = 0; i < width * height; ++i, inPixel32Count += sizeof(int)) { d32 = Marshal.ReadInt32(data, inPixel32Count); short R = (short)((((d32 >> 0) & 0xFF) >> 3) << 11); short G = (short)((((d32 >> 8) & 0xFF) >> 2) << 5); short B = (short)((((d32 >> 16) & 0xFF) >> 3) << 0); d16 = (short)(R | G | B); Marshal.WriteInt16(tempData, outPixel16Count, d16); outPixel16Count += sizeof(short); } Marshal.FreeHGlobal(data); data = tempData; } InitWithData(data, pixelFormat, width, height, imageSize, filter); context.Dispose(); Marshal.FreeHGlobal(data); }
public static UIImage MakeRoundCornerImage(UIImage img, int cornerWidth, int cornerHeight) { UIImage newImage = null; if (null != img) { var w = img.Size.Width; var h = img.Size.Height; CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB(); CGContext context = new CGBitmapContext(null, (int)w, (int)h, 8, (int)(4 * w), colorSpace, CGImageAlphaInfo.PremultipliedFirst); context.BeginPath(); var rect = new RectangleF(0, 0, img.Size.Width, img.Size.Height); AddRoundedRectToPath (context, rect, cornerWidth, cornerHeight); context.ClosePath(); context.Clip(); var cgImage = img.CGImage; context.DrawImage (new RectangleF(0, 0, w, h), cgImage); cgImage.Dispose(); CGImage imageMasked = ((CGBitmapContext)context).ToImage(); context.Dispose(); colorSpace.Dispose(); newImage = new UIImage(imageMasked); imageMasked.Dispose(); } return newImage; }
private void InitWithCGImage(CGImage image, All filter) { int width,height,i; CGContext context = null; IntPtr data; CGColorSpace colorSpace; IntPtr tempData; bool hasAlpha; CGImageAlphaInfo info; CGAffineTransform transform; Size imageSize; SurfaceFormat pixelFormat; bool sizeToFit = false; if(image == null) { throw new ArgumentException(" uimage is invalid! " ); } info = image.AlphaInfo; hasAlpha = ((info == CGImageAlphaInfo.PremultipliedLast) || (info == CGImageAlphaInfo.PremultipliedFirst) || (info == CGImageAlphaInfo.Last) || (info == CGImageAlphaInfo.First) ? true : false); if (image.ColorSpace != null) { pixelFormat = SurfaceFormat.Color; } else { pixelFormat = SurfaceFormat.Alpha8; } imageSize = new Size(image.Width,image.Height); transform = CGAffineTransform.MakeIdentity(); width = imageSize.Width; if((width != 1) && ((width & (width - 1))!=0)) { i = 1; while((sizeToFit ? 2 * i : i) < width) i *= 2; width = i; } height = imageSize.Height; if((height != 1) && ((height & (height - 1))!=0)) { i = 1; while((sizeToFit ? 2 * i : i) < height) i *= 2; height = i; } // TODO: kMaxTextureSize = 1024 while((width > 1024) || (height > 1024)) { width /= 2; height /= 2; transform = CGAffineTransform.MakeScale(0.5f,0.5f); imageSize.Width /= 2; imageSize.Height /= 2; } switch(pixelFormat) { case SurfaceFormat.Color: colorSpace = CGColorSpace.CreateDeviceRGB(); data = Marshal.AllocHGlobal(height * width * 4); context = new CGBitmapContext(data, width, height, 8, 4 * width, colorSpace,CGImageAlphaInfo.PremultipliedLast); colorSpace.Dispose(); break; case SurfaceFormat.Alpha8: data = Marshal.AllocHGlobal(height * width); context = new CGBitmapContext(data, width, height, 8, width, null, CGImageAlphaInfo.Only); break; default: throw new NotSupportedException("Invalid pixel format"); } context.ClearRect(new RectangleF(0,0,width,height)); context.TranslateCTM(0, height - imageSize.Height); if (!transform.IsIdentity) { context.ConcatCTM(transform); } context.DrawImage(new RectangleF(0, 0, image.Width, image.Height), image); //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB" /* if(pixelFormat == SurfaceFormat.Rgb32) { tempData = Marshal.AllocHGlobal(height * width * 2); int d32; short d16; int inPixel32Count=0,outPixel16Count=0; for(i = 0; i < width * height; ++i, inPixel32Count+=sizeof(int)) { d32 = Marshal.ReadInt32(data,inPixel32Count); short R = (short)((((d32 >> 0) & 0xFF) >> 3) << 11); short G = (short)((((d32 >> 8) & 0xFF) >> 2) << 5); short B = (short)((((d32 >> 16) & 0xFF) >> 3) << 0); d16 = (short) (R | G | B); Marshal.WriteInt16(tempData,outPixel16Count,d16); outPixel16Count += sizeof(short); } Marshal.FreeHGlobal(data); data = tempData; } */ InitWithData(data,pixelFormat,width,height,imageSize, filter); context.Dispose(); Marshal.FreeHGlobal (data); }
public bool Finalize (IMTLDevice device) { if (MetalTexture != null) return true; UIImage image = UIImage.FromFile (path); if (image == null) return false; using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB ()) { if (colorSpace == null) return false; Width = image.CGImage.Width; Height = image.CGImage.Height; nuint width = (nuint)Width; nuint height = (nuint)Height; nuint rowBytes = width * 4; var context = new CGBitmapContext (IntPtr.Zero, (int)width, (int)height, 8, (int)rowBytes, colorSpace, CGImageAlphaInfo.PremultipliedLast); if (context == null) return false; var bounds = new CGRect (0f, 0f, width, height); context.ClearRect (bounds); // Vertical Reflect if (flip) { context.TranslateCTM (width, height); context.ScaleCTM (-1f, -1f); } context.DrawImage (bounds, image.CGImage); MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.RGBA8Unorm, width, height, false); if (texDesc == null) return false; MetalTexture = device.CreateTexture (texDesc); if (MetalTexture == null) { context.Dispose (); return false; } IntPtr pixels = context.Data; if (pixels != IntPtr.Zero) { var region = new MTLRegion (); region.Origin.X = 0; region.Origin.Y = 0; region.Size.Width = (nint)width; region.Size.Height = (nint)height; MetalTexture.ReplaceRegion (region, 0, pixels, rowBytes); } context.Dispose (); } return true; }
public static UIImage RemoveColor(UIImage image, UIColor color, float tolerance) { // convert color to RGBA (may be greyscale for example); nfloat r, g, b, a; color.GetRGBA(out r, out g, out b, out a); color = UIColor.FromRGBA(r, g, b, a); var imageRef = image.CGImage; var width = (int)imageRef.Width; var height = (int)imageRef.Height; var colorSpace = CGColorSpace.CreateDeviceRGB(); var bytesPerPixel = 4; var bytesPerRow = bytesPerPixel * width; var bitsPerComponent = 8; var bitmapByteCount = bytesPerRow * height; byte[] rawData = new byte[bitmapByteCount]; var context = new CGBitmapContext( rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrder32Big); colorSpace.Dispose(); context.DrawImage(new CGRect(0, 0, width, height), imageRef); var cgColor = color.CGColor; var components = cgColor.Components; r = components[0]; g = components[1]; b = components[2]; //float a = components[3]; // not needed r = r * 255.0f; g = g * 255.0f; b = b * 255.0f; var redRange = new[] { (nfloat)Math.Max(r - (tolerance / 2.0f), 0.0f), (nfloat)Math.Min(r + (tolerance / 2.0f), 255.0f) }; var greenRange = new[] { (nfloat)Math.Max(g - (tolerance / 2.0f), 0.0f), (nfloat)Math.Min(g + (tolerance / 2.0f), 255.0f) }; var blueRange = new[] { (nfloat)Math.Max(b - (tolerance / 2.0f), 0.0f), (nfloat)Math.Min(b + (tolerance / 2.0f), 255.0f) }; int byteIndex = 0; while (byteIndex < bitmapByteCount) { var red = rawData[byteIndex]; var green = rawData[byteIndex + 1]; var blue = rawData[byteIndex + 2]; if (((red >= redRange[0]) && (red <= redRange[1])) && ((green >= greenRange[0]) && (green <= greenRange[1])) && ((blue >= blueRange[0]) && (blue <= blueRange[1]))) { // make the pixel transparent // rawData[byteIndex] = 0; rawData[byteIndex + 1] = 0; rawData[byteIndex + 2] = 0; rawData[byteIndex + 3] = 0; } byteIndex += 4; } var result = new UIImage(context.ToImage()); context.Dispose(); return(result); }
static CGImage applyMosaic(int tileSize, List <Color> colorPalette, UIImage resizedImg, Bitmap bitmap) { // - Parameters int width = tileSize; // tile width int height = tileSize; // tile height int outWidth = (int)(resizedImg.Size.Width - (resizedImg.Size.Width % width)); // Round image size int outHeight = (int)(resizedImg.Size.Height - (resizedImg.Size.Height % height)); // -- Initialize buffer CGBitmapContext context = new CGBitmapContext(System.IntPtr.Zero, // data (int)outWidth, // width (int)outHeight, // height 8, // bitsPerComponent outWidth * 4, // bytesPerRow based on pixel width CGColorSpace.CreateDeviceRGB(), // colorSpace CGImageAlphaInfo.NoneSkipFirst); // bitmapInfo for (int yb = 0; yb < outHeight / height; yb++) { for (int xb = 0; xb < outWidth / width; xb++) { // -- Do the average colors on the source image for the // corresponding mosaic square int r_avg = 0; int g_avg = 0; int b_avg = 0; for (int y = yb * height; y < (yb * height) + height; y++) { for (int x = xb * width; x < (xb * width) + width; x++) { Color c = bitmap.GetPixel(x, y); // Retrieve color values of the source image r_avg += c.R; g_avg += c.G; b_avg += c.B; } } // Make average of R,G and B on filter size r_avg = r_avg / (width * height); g_avg = g_avg / (width * height); b_avg = b_avg / (width * height); // Find the nearest color in the palette Color mosaicColor = new Color(); double minDistance = int.MaxValue; foreach (Color c in colorPalette) { double distance = Math.Abs(Math.Pow(r_avg - c.R, 2) + Math.Pow(g_avg - c.G, 2) + Math.Pow(b_avg - c.B, 2)); if (distance < minDistance) { mosaicColor = c; minDistance = distance; } } // Apply mosaic for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { context.SetFillColor(new CGColor(mosaicColor.R / 255f, mosaicColor.G / 255f, mosaicColor.B / 255f)); context.FillRect(new RectangleF(xb * width, yb * height, width, height)); } } } } //-- image from buffer CGImage flippedImage = context.ToImage(); context.Dispose(); return(flippedImage); }
public ESTexture2D(UIImage uiImage, All filter) { CGImage image = uiImage.CGImage; if(uiImage == null) throw new ArgumentNullException("uiImage"); // TODO: could use this to implement lower-bandwidth textures //bool hasAlpha = (image.AlphaInfo == CGImageAlphaInfo.First || image.AlphaInfo == CGImageAlphaInfo.Last // || image.AlphaInfo == CGImageAlphaInfo.PremultipliedFirst || image.AlphaInfo == CGImageAlphaInfo.PremultipliedLast); // Image dimentions: logicalSize = new Point((int)uiImage.Size.Width, (int)uiImage.Size.Height); pixelWidth = uiImage.CGImage.Width; pixelHeight = uiImage.CGImage.Height; // Round up the target texture width and height to powers of two: potWidth = pixelWidth; potHeight = pixelHeight; if(( potWidth & ( potWidth-1)) != 0) { int w = 1; while(w < potWidth) { w *= 2; } potWidth = w; } if((potHeight & (potHeight-1)) != 0) { int h = 1; while(h < potHeight) { h *= 2; } potHeight = h; } // Scale down textures that are too large... CGAffineTransform transform = CGAffineTransform.MakeIdentity(); while((potWidth > 1024) || (potHeight > 1024)) { potWidth /= 2; // Note: no precision loss - it's a power of two potHeight /= 2; pixelWidth /= 2; // Note: precision loss - assume possibility of dropping a pixel at each step is ok pixelHeight /= 2; transform.Multiply(CGAffineTransform.MakeScale(0.5f, 0.5f)); } RecalculateRatio(); lock(textureLoadBufferLockObject) { CreateTextureLoadBuffer(); unsafe { fixed(byte* data = textureLoadBuffer) { var colorSpace = CGColorSpace.CreateDeviceRGB(); var context = new CGBitmapContext(new IntPtr(data), potWidth, potHeight, 8, 4 * potWidth, colorSpace, CGImageAlphaInfo.PremultipliedLast); context.ClearRect(new RectangleF(0, 0, potWidth, potHeight)); context.TranslateCTM(0, potHeight - pixelHeight); // TODO: this does not play nice with the precision-loss above (keeping half-pixel to the edge) if(!transform.IsIdentity) context.ConcatCTM(transform); context.DrawImage(new RectangleF(0, 0, image.Width, image.Height), image); SetupTexture(new IntPtr(data), filter); context.Dispose(); colorSpace.Dispose(); } } } }
public static UIImage FixOrientation(UIImage originalImage) { if (originalImage.Orientation == UIImageOrientation.Up) { return(originalImage); } CGAffineTransform transform = CGAffineTransform.MakeIdentity(); switch (originalImage.Orientation) { case UIImageOrientation.Down: case UIImageOrientation.DownMirrored: transform.Rotate((float)Math.PI); transform.Translate(originalImage.Size.Width, originalImage.Size.Height); break; case UIImageOrientation.Left: case UIImageOrientation.LeftMirrored: transform.Rotate((float)Math.PI / 2); transform.Translate(originalImage.Size.Width, 0); break; case UIImageOrientation.Right: case UIImageOrientation.RightMirrored: transform.Rotate(-(float)Math.PI / 2); transform.Translate(0, originalImage.Size.Height); break; case UIImageOrientation.Up: case UIImageOrientation.UpMirrored: break; } switch (originalImage.Orientation) { case UIImageOrientation.UpMirrored: case UIImageOrientation.DownMirrored: transform.Translate(originalImage.Size.Width, 0); transform.Scale(-1, 1); break; case UIImageOrientation.LeftMirrored: case UIImageOrientation.RightMirrored: transform.Translate(originalImage.Size.Height, 0); transform.Scale(-1, 1); break; case UIImageOrientation.Up: case UIImageOrientation.Down: case UIImageOrientation.Left: case UIImageOrientation.Right: break; } var ctx = new CGBitmapContext(IntPtr.Zero, (nint)originalImage.Size.Width, (nint)originalImage.Size.Height, originalImage.CGImage.BitsPerComponent, originalImage.CGImage.BytesPerRow, originalImage.CGImage.ColorSpace, originalImage.CGImage.BitmapInfo); ctx.ConcatCTM(transform); switch (originalImage.Orientation) { case UIImageOrientation.Left: case UIImageOrientation.LeftMirrored: case UIImageOrientation.Right: case UIImageOrientation.RightMirrored: ctx.DrawImage(new CGRect(0, 0, originalImage.Size.Height, originalImage.Size.Width), originalImage.CGImage); break; default: ctx.DrawImage(new CGRect(0, 0, originalImage.Size.Width, originalImage.Size.Height), originalImage.CGImage); break; } var cgImage = ctx.ToImage(); UIImage result = UIImage.FromImage(cgImage); ctx.Dispose(); cgImage.Dispose(); return(result); }
public static TextureData FromUIImage(UIImage uiImage) { if (uiImage == null) { throw new ArgumentNullException("uiImage"); } var image = uiImage.CGImage; if (image == null) { throw new ArgumentNullException("uiImage.CGImage"); } var info = image.AlphaInfo; var hasAlpha = ((info == CGImageAlphaInfo.PremultipliedLast) || (info == CGImageAlphaInfo.PremultipliedFirst) || (info == CGImageAlphaInfo.Last) || (info == CGImageAlphaInfo.First)); var pixelFormat = TexturePixelFormat.RGBA8888; if (image.ColorSpace != null) { if (hasAlpha) { pixelFormat = TexturePixelFormat.RGBA8888; } else { pixelFormat = TexturePixelFormat.RGB565; } } else //NOTE: No colorspace means a mask image { pixelFormat = TexturePixelFormat.A8; } var width = image.Width; var height = image.Height; var data = IntPtr.Zero; CGBitmapContext context = null; switch (pixelFormat) { case TexturePixelFormat.RGBA8888: using (var colorSpace = CGColorSpace.CreateDeviceRGB()) { data = Marshal.AllocHGlobal(height * width * 4); context = new CGBitmapContext(data, width, height, 8, 4 * width, colorSpace, (CGImageAlphaInfo)((uint)CGImageAlphaInfo.PremultipliedLast | (uint)CGBitmapFlags.ByteOrder32Big)); } break; case TexturePixelFormat.RGB565: using (var colorSpace = CGColorSpace.CreateDeviceRGB()) { data = Marshal.AllocHGlobal(height * width * 4); context = new CGBitmapContext(data, width, height, 8, 4 * width, colorSpace, (CGImageAlphaInfo)((uint)CGImageAlphaInfo.NoneSkipLast | (uint)CGBitmapFlags.ByteOrder32Big)); } break; case TexturePixelFormat.A8: data = Marshal.AllocHGlobal(height * width); context = new CGBitmapContext(data, width, height, 8, width, null, CGImageAlphaInfo.Only); break; default: throw new NotSupportedException(pixelFormat + " is not supported"); } context.ClearRect(new RectangleF(0, 0, width, height)); context.DrawImage(new RectangleF(0, 0, width, height), image); context.Dispose(); if (pixelFormat == TexturePixelFormat.RGB565) { var tempData = Marshal.AllocHGlobal(height * width * 2); unsafe { var inPixel32 = (uint *)data; var outPixel16 = (ushort *)tempData; for (var i = 0; i < width * height; ++i, ++inPixel32) { *outPixel16++ = (ushort)(((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | ((((*inPixel32 >> 8) & 0xFF) >> 2) << 5) | ((((*inPixel32 >> 16) & 0xFF) >> 3) << 0)); } } Marshal.FreeHGlobal(data); data = tempData; } return(new TextureData(data, pixelFormat, width, height)); }
public bool Finalize(IMTLDevice device) { if (MetalTexture != null) { return(true); } UIImage image = UIImage.FromFile(path); if (image == null) { return(false); } using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB()) { if (colorSpace == null) { return(false); } Width = image.CGImage.Width; Height = image.CGImage.Height; nuint width = (nuint)Width; nuint height = (nuint)Height; nuint rowBytes = width * 4; var context = new CGBitmapContext(IntPtr.Zero, (int)width, (int)height, 8, (int)rowBytes, colorSpace, CGImageAlphaInfo.PremultipliedLast); if (context == null) { return(false); } var bounds = new CGRect(0f, 0f, width, height); context.ClearRect(bounds); // Vertical Reflect if (flip) { context.TranslateCTM(width, height); context.ScaleCTM(-1f, -1f); } context.DrawImage(bounds, image.CGImage); MTLTextureDescriptor texDesc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.RGBA8Unorm, width, height, false); if (texDesc == null) { return(false); } MetalTexture = device.CreateTexture(texDesc); if (MetalTexture == null) { context.Dispose(); return(false); } IntPtr pixels = context.Data; if (pixels != IntPtr.Zero) { var region = new MTLRegion(); region.Origin.X = 0; region.Origin.Y = 0; region.Size.Width = (nint)width; region.Size.Height = (nint)height; MetalTexture.ReplaceRegion(region, 0, pixels, rowBytes); } context.Dispose(); } return(true); }
public override object ConvertToBitmap(ImageDescription idesc, double scaleFactor, ImageFormat format) { double width = idesc.Size.Width; double height = idesc.Size.Height; int pixelWidth = (int)(width * scaleFactor); int pixelHeight = (int)(height * scaleFactor); if (idesc.Backend is CustomImage) { var flags = CGBitmapFlags.ByteOrderDefault; int bytesPerRow; switch (format) { case ImageFormat.ARGB32: bytesPerRow = pixelWidth * 4; flags |= CGBitmapFlags.PremultipliedFirst; break; case ImageFormat.RGB24: bytesPerRow = pixelWidth * 3; flags |= CGBitmapFlags.None; break; default: throw new NotImplementedException("ImageFormat: " + format.ToString()); } var bmp = new CGBitmapContext(IntPtr.Zero, pixelWidth, pixelHeight, 8, bytesPerRow, Util.DeviceRGBColorSpace, flags); bmp.TranslateCTM(0, pixelHeight); bmp.ScaleCTM((float)scaleFactor, (float)-scaleFactor); var ctx = new CGContextBackend { Context = bmp, Size = new CGSize((nfloat)width, (nfloat)height), InverseViewTransform = bmp.GetCTM().Invert(), ScaleFactor = scaleFactor }; var ci = (CustomImage)idesc.Backend; ci.DrawInContext(ctx, idesc); var img = new NSImage(((CGBitmapContext)bmp).ToImage(), new CGSize(pixelWidth, pixelHeight)); var imageData = img.AsTiff(); var imageRep = (NSBitmapImageRep)NSBitmapImageRep.ImageRepFromData(imageData); var im = new NSImage(); im.AddRepresentation(imageRep); im.Size = new CGSize((nfloat)width, (nfloat)height); bmp.Dispose(); return(im); } else { NSImage img = (NSImage)idesc.Backend; NSBitmapImageRep bitmap = img.Representations().OfType <NSBitmapImageRep> ().FirstOrDefault(); if (bitmap == null) { var imageData = img.AsTiff(); var imageRep = (NSBitmapImageRep)NSBitmapImageRep.ImageRepFromData(imageData); var im = new NSImage(); im.AddRepresentation(imageRep); im.Size = new CGSize((nfloat)width, (nfloat)height); return(im); } return(idesc.Backend); } }
public void GetData <T>(int level, Rectangle?rect, T[] data, int startIndex, int elementCount) { if (data == null) { throw new ArgumentException("data cannot be null"); } if (data.Length < startIndex + elementCount) { throw new ArgumentException("The data passed has a length of " + data.Length + " but " + elementCount + " pixels have been requested."); } Rectangle r; if (rect != null) { r = rect.Value; } else { r = new Rectangle(0, 0, Width, Height); } int sz = 0; byte[] pixel = new byte[4]; int pos; IntPtr pixelOffset; // Get the Color values if ((typeof(T) == typeof(Color))) { // Load up texture into memory UIImage uiImage = UIImage.FromBundle(this.Name); if (uiImage == null) { throw new ContentLoadException("Error loading file via UIImage: " + Name); } CGImage image = uiImage.CGImage; if (image == null) { throw new ContentLoadException("Error with CGIamge: " + Name); } int width, height, i; CGContext context = null; IntPtr imageData; CGColorSpace colorSpace; IntPtr tempData; bool hasAlpha; CGImageAlphaInfo info; CGAffineTransform transform; Size imageSize; SurfaceFormat pixelFormat; bool sizeToFit = false; info = image.AlphaInfo; hasAlpha = ((info == CGImageAlphaInfo.PremultipliedLast) || (info == CGImageAlphaInfo.PremultipliedFirst) || (info == CGImageAlphaInfo.Last) || (info == CGImageAlphaInfo.First) ? true : false); if (image.ColorSpace != null) { pixelFormat = SurfaceFormat.Color; } else { pixelFormat = SurfaceFormat.Alpha8; } imageSize = new Size(image.Width, image.Height); transform = CGAffineTransform.MakeIdentity(); width = imageSize.Width; if ((width != 1) && ((width & (width - 1)) != 0)) { i = 1; while ((sizeToFit ? 2 * i : i) < width) { i *= 2; } width = i; } height = imageSize.Height; if ((height != 1) && ((height & (height - 1)) != 0)) { i = 1; while ((sizeToFit ? 2 * i : i) < height) { i *= 2; } height = i; } // TODO: kMaxTextureSize = 1024 while ((width > 1024) || (height > 1024)) { width /= 2; height /= 2; transform = CGAffineTransform.MakeScale(0.5f, 0.5f); imageSize.Width /= 2; imageSize.Height /= 2; } switch (pixelFormat) { case SurfaceFormat.Color: colorSpace = CGColorSpace.CreateDeviceRGB(); imageData = Marshal.AllocHGlobal(height * width * 4); context = new CGBitmapContext(imageData, width, height, 8, 4 * width, colorSpace, CGImageAlphaInfo.PremultipliedLast); colorSpace.Dispose(); break; case SurfaceFormat.Alpha8: imageData = Marshal.AllocHGlobal(height * width); context = new CGBitmapContext(imageData, width, height, 8, width, null, CGImageAlphaInfo.Only); break; default: throw new NotSupportedException("Invalid pixel format"); } context.ClearRect(new RectangleF(0, 0, width, height)); context.TranslateCTM(0, height - imageSize.Height); if (!transform.IsIdentity) { context.ConcatCTM(transform); } context.DrawImage(new RectangleF(0, 0, image.Width, image.Height), image); //Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB" /* * if(pixelFormat == SurfaceFormat.Rgb32) { * tempData = Marshal.AllocHGlobal(height * width * 2); * * int d32; * short d16; * int inPixel32Count=0,outPixel16Count=0; * for(i = 0; i < width * height; ++i, inPixel32Count+=sizeof(int)) * { * d32 = Marshal.ReadInt32(imageData,inPixel32Count); * short R = (short)((((d32 >> 0) & 0xFF) >> 3) << 11); * short G = (short)((((d32 >> 8) & 0xFF) >> 2) << 5); * short B = (short)((((d32 >> 16) & 0xFF) >> 3) << 0); * d16 = (short) (R | G | B); * Marshal.WriteInt16(tempData,outPixel16Count,d16); * outPixel16Count += sizeof(short); * } * Marshal.FreeHGlobal(imageData); * imageData = tempData; * } */ int count = 0; // Loop through and extract the data for (int y = r.Top; y < r.Bottom; y++) { for (int x = r.Left; x < r.Right; x++) { var result = new Color(0, 0, 0, 0); switch (this.Format) { case SurfaceFormat.Color /*kTexture2DPixelFormat_RGBA8888*/: case SurfaceFormat.Dxt3: sz = 4; pos = ((y * imageSize.Width) + x) * sz; pixelOffset = new IntPtr(imageData.ToInt64() + pos); Marshal.Copy(pixelOffset, pixel, 0, 4); result.R = pixel[0]; result.G = pixel[1]; result.B = pixel[2]; result.A = pixel[3]; break; case SurfaceFormat.Bgra4444 /*kTexture2DPixelFormat_RGBA4444*/: sz = 2; pos = ((y * imageSize.Width) + x) * sz; pixelOffset = new IntPtr(imageData.ToInt64() + pos); Marshal.Copy(pixelOffset, pixel, 0, 4); result.R = pixel[0]; result.G = pixel[1]; result.B = pixel[2]; result.A = pixel[3]; break; case SurfaceFormat.Bgra5551 /*kTexture2DPixelFormat_RGB5A1*/: sz = 2; pos = ((y * imageSize.Width) + x) * sz; pixelOffset = new IntPtr(imageData.ToInt64() + pos); Marshal.Copy(pixelOffset, pixel, 0, 4); result.R = pixel[0]; result.G = pixel[1]; result.B = pixel[2]; result.A = pixel[3]; break; case SurfaceFormat.Alpha8 /*kTexture2DPixelFormat_A8*/: sz = 1; pos = ((y * imageSize.Width) + x) * sz; pixelOffset = new IntPtr(imageData.ToInt64() + pos); Marshal.Copy(pixelOffset, pixel, 0, 4); result.A = pixel[0]; break; default: throw new NotSupportedException("Texture format"); } data[((y * imageSize.Width) + x)] = (T)(object)result; count++; if (count >= elementCount) { return; } } } context.Dispose(); Marshal.FreeHGlobal(imageData); } else { throw new NotImplementedException(); } }