Example #1
0
        public void SetPixel(int x, int y, Color color)
        {
            if (x < 0 || x > NativeCGImage.Width - 1)
            {
                throw new InvalidEnumArgumentException("Parameter must be positive and < Width.");
            }
            if (y < 0 || y > NativeCGImage.Height - 1)
            {
                throw new InvalidEnumArgumentException("Parameter must be positive and < Height.");
            }

            if (cachedContext == null || cachedContext.Handle == IntPtr.Zero)
            {
                GetRenderableContext();
            }

            // We are going to cheat here by drawing directly to the cached context that is
            // associated to the image.  This way we do not have to play with pixels and offsets
            // to change the data.  If this proves to be non performant then we will change it later.
            cachedContext.SaveState();
            cachedContext.ConcatCTM(cachedContext.GetCTM().Invert());
            cachedContext.ConcatCTM(imageTransform);
            cachedContext.SetFillColor(color);
            cachedContext.FillRect(new CGRect(x, y, 1, 1));
            cachedContext.FillPath();
            cachedContext.RestoreState();
        }
Example #2
0
        /// <summary>
        /// Renders the image given the specified parameters.
        /// </summary>
        /// <param name="components">Number of components.</param>
        /// <param name="flipX">Flip image in X direction?</param>
        /// <param name="flipY">Flip image in Y direction?</param>
        /// <param name="rotation">Image rotation.</param>
        public override void Render(int components, bool flipX, bool flipY, int rotation)
        {
            // Switch R and B components before rendering.
            var length = SizeOfRgba * this.width * this.height;
            var bytes  = new byte[length];

            Marshal.Copy(this.pixels.Pointer, bytes, 0, length);

            for (var k = 0; k < length; k += 4)
            {
                var tmp = bytes[k];
                bytes[k]     = bytes[k + 2];
                bytes[k + 2] = tmp;
            }

            using (
                var context = new CGBitmapContext(
                    bytes,
                    this.width,
                    this.height,
                    8,
                    SizeOfRgba * this.width,
                    CGColorSpace.CreateDeviceRGB(),
                    CGImageAlphaInfo.PremultipliedLast))
            {
                var transform = CGAffineTransform.MakeRotation((float)(rotation * Math.PI / 180.0));
                transform.Scale(flipX ? -1.0f : 1.0f, flipY ? -1.0f : 1.0f);
                transform.Translate(flipX ? this.width : 0.0f, flipY ? this.height : 0.0f);
                context.ConcatCTM(transform);

                this.image = context.ToImage();
            }
        }
Example #3
0
        // Draws our animation path on the background image, just to show it
        void DrawPathAsBackground()
        {
            // create our offscreen bitmap context
            var bitmapSize = new CGSize(View.Frame.Size);

            using (var context = new CGBitmapContext(
                       IntPtr.Zero,
                       (int)bitmapSize.Width, (int)bitmapSize.Height, 8,
                       (int)(4 * bitmapSize.Width), CGColorSpace.CreateDeviceRGB(),
                       CGImageAlphaInfo.PremultipliedFirst)) {
                // convert to View space
                var affineTransform = CGAffineTransform.MakeIdentity();
                // invert the y axis
                affineTransform.Scale(1f, -1f);
                // move the y axis up
                affineTransform.Translate(0, View.Frame.Height);
                context.ConcatCTM(affineTransform);

                // actually draw the path
                context.AddPath(animationPath);
                context.SetStrokeColor(UIColor.LightGray.CGColor);
                context.SetLineWidth(3f);
                context.StrokePath();

                // set what we've drawn as the backgound image
                backgroundImage.Image = UIImage.FromImage(context.ToImage());
            }
        }
        /// <summary>
        /// Draws our animation path on the background image, just to show it
        /// </summary>
        protected void DrawPathAsBackground()
        {
            //---- create our offscreen bitmap context
            // size
            SizeF bitmapSize = new SizeF(this.View.Frame.Size);

            using (CGBitmapContext context = new CGBitmapContext(IntPtr.Zero
                                                                 , (int)bitmapSize.Width, (int)bitmapSize.Height, 8
                                                                 , (int)(4 * bitmapSize.Width), CGColorSpace.CreateDeviceRGB()
                                                                 , CGImageAlphaInfo.PremultipliedFirst))
            {
                //---- convert to View space
                CGAffineTransform affineTransform = CGAffineTransform.MakeIdentity();
                //---- invert the y axis
                affineTransform.Scale(1, -1);
                //---- move the y axis up
                affineTransform.Translate(0, this.View.Frame.Height);
                context.ConcatCTM(affineTransform);

                //---- actually draw the path
                context.AddPath(this._animationPath);
                context.SetStrokeColorWithColor(UIColor.LightGray.CGColor);
                context.SetLineWidth(3);
                context.StrokePath();

                //---- set what we've drawn as the backgound image
                this._backgroundImage.Image = UIImage.FromImage(context.ToImage());
            }
        }
        public static XIR.Image RemoteRepresentation(this NSAttributedString attributedString)
        {
            var typesetter = new CTTypesetter(attributedString);
            var measure    = CGSize.Empty;

            var count = typesetter.SuggestLineBreak(0, 8388608);
            var line  = typesetter.GetLine(new NSRange(0, count));

            // Create and initialize some values from the bounds.
            nfloat ascent;
            nfloat descent;
            nfloat leading;
            var    lineWidth = line.GetTypographicBounds(out ascent, out descent, out leading);

            measure.Height += (float)Math.Ceiling(ascent + descent + leading + 1);  // +1 matches best to CTFramesetter's behavior
            measure.Width   = (float)lineWidth;

            var width  = (int)measure.Width > 0 ? (int)measure.Width : 200;
            var height = (int)measure.Height > 0 ? (int)measure.Height : 200;

            var bytesPerRow = width * 4;

            using (var context = new CGBitmapContext(
                       IntPtr.Zero, width, height,
                       8, bytesPerRow, CGColorSpace.CreateDeviceRGB(),
                       CGImageAlphaInfo.PremultipliedFirst))
            {
                context.ConcatCTM(context.GetCTM().Invert());
                var matrix = new CGAffineTransform(
                    1, 0, 0, -1, 0, height);

                context.ConcatCTM(matrix);
                var textMatrix = new CGAffineTransform(
                    1, 0, 0, -1, 0, ascent);

                context.TextMatrix = textMatrix;
                line.Draw(context);
                line.Dispose();

                return(RemoteRepresentation(context));
            }
        }
Example #6
0
        public static void BeginImageContextWithOptions(CGSize size, bool opaque, nfloat scale)
        {
            // Create new image context
            ColorSpace = CGColorSpace.CreateDeviceRGB ();
            Context = new CGBitmapContext (null, (int)size.Width, (int)size.Height, 8, 0, ColorSpace, CGImageAlphaInfo.PremultipliedLast);

            // Flip context vertically
            var flipVertical = new  CGAffineTransform(1,0,0,-1,0,size.Height);
            Context.ConcatCTM (flipVertical);

            // Save previous context
            ImageSize = size;
            PreviousContext = NSGraphicsContext.CurrentContext;
            NSGraphicsContext.CurrentContext = NSGraphicsContext.FromCGContext (Context, true);
        }
Example #7
0
        public static void BeginImageContextWithOptions(CGSize size, bool opaque, nfloat scale)
        {
            // Create new image context
            ColorSpace = CGColorSpace.CreateDeviceRGB();
            Context    = new CGBitmapContext(null, (int)size.Width, (int)size.Height, 8, 0, ColorSpace, CGImageAlphaInfo.PremultipliedLast);

            // Flip context vertically
            var flipVertical = new  CGAffineTransform(1, 0, 0, -1, 0, size.Height);

            Context.ConcatCTM(flipVertical);

            // Save previous context
            ImageSize       = size;
            PreviousContext = NSGraphicsContext.CurrentContext;
            NSGraphicsContext.CurrentContext = NSGraphicsContext.FromCGContext(Context, true);
        }
Example #8
0
        /// <summary>
        /// Returns thumb image object for page
        /// </summary>
        /// <param name="thumbContentSize">Thumb content size</param>
        /// <param name="pageNumber">Page number for what will created image object</param>
        /// <returns>Page image object</returns>
        private static UIImage GetThumbImage(float thumbContentSize, int pageNumber)
        {
            if ((pageNumber <= 0) || (pageNumber > PDFDocument.PageCount))
            {
                return(null);
            }

            // Calc page view size
            var pageSize = PageContentView.GetPageViewSize(pageNumber);

            if (pageSize.Width % 2 > 0)
            {
                pageSize.Width--;
            }
            if (pageSize.Height % 2 > 0)
            {
                pageSize.Height--;
            }

            // Calc target size
            var targetSize = new Size((int)pageSize.Width, (int)pageSize.Height);

            // Draw page on CGImage
            CGImage pageImage;

            using (CGColorSpace rgb = CGColorSpace.CreateDeviceRGB()) {
                using (var context = new CGBitmapContext(null, targetSize.Width, targetSize.Height, 8, 0, rgb, CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.NoneSkipFirst)) {
                    using (var pdfPage = PDFDocument.GetPage(pageNumber)) {
                        // Draw page on custom CGBitmap context
                        var thumbRect = new RectangleF(0.0f, 0.0f, targetSize.Width, targetSize.Height);
                        context.SetFillColor(1.0f, 1.0f, 1.0f, 1.0f);
                        context.FillRect(thumbRect);
                        context.ConcatCTM(pdfPage.GetDrawingTransform(CGPDFBox.Crop, thumbRect, 0, true));
                        context.SetRenderingIntent(CGColorRenderingIntent.Default);
                        context.InterpolationQuality = CGInterpolationQuality.Default;
                        context.DrawPDFPage(pdfPage);
                        // Create CGImage from custom CGBitmap context
                        pageImage = context.ToImage();
                    }
                }
            }
            return(UIImage.FromImage(pageImage));
        }
Example #9
0
        protected override void UpdateCapturedImage()
        {
            if (view != null && layer == null)
            {
                var bitmap = view.BitmapImageRepForCachingDisplayInRect(view.Bounds);
                if (bitmap == null)
                {
                    return;
                }

                view.CacheDisplay(view.Bounds, bitmap);
                var data = bitmap.RepresentationUsingTypeProperties(NSBitmapImageFileType.Png);
                CapturedImage = data.ToArray();
            }
            else if (layer != null)
            {
                var  scale       = layer.ContentsScale;
                nint h           = (nint)(layer.Bounds.Height * scale);
                nint w           = (nint)(layer.Bounds.Width * scale);
                nint bytesPerRow = w * 4;

                if (h <= 0 || w <= 0)
                {
                    return;
                }

                using (var colorSpace = CGColorSpace.CreateGenericRgb())
                    using (var context = new CGBitmapContext(IntPtr.Zero, w, h, 8, bytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedLast)) {
                        // Apply a flipping transform because layers are apparently weird.
                        var transform = new CGAffineTransform(scale, 0, 0, -scale, 0, h);
                        context.ConcatCTM(transform);

                        layer.RenderInContext(context);

                        using (var image = context.ToImage())
                            using (var bitmap = new NSBitmapImageRep(image)) {
                                var data = bitmap.RepresentationUsingTypeProperties(NSBitmapImageFileType.Png);
                                CapturedImage = data.ToArray();
                            }
                    }
            }
        }
Example #10
0
        /// <summary>
        /// Renders the image given the specified parameters.
        /// </summary>
        /// <param name="components">Number of components.</param>
        /// <param name="flipX">Flip image in X direction?</param>
        /// <param name="flipY">Flip image in Y direction?</param>
        /// <param name="rotation">Image rotation.</param>
        public override void Render(int components, bool flipX, bool flipY, int rotation)
        {
            using (
                var context = new CGBitmapContext(
                    this.pixels.Pointer,
                    this.width,
                    this.height,
                    8,
                    4 * this.width,
                    CGColorSpace.CreateDeviceRGB(),
                    CGImageAlphaInfo.PremultipliedLast))
            {
                var transform = CGAffineTransform.MakeRotation((float)(rotation * Math.PI / 180.0));
                transform.Scale(flipX ? -1.0f : 1.0f, flipY ? -1.0f : 1.0f);
                transform.Translate(flipX ? this.width : 0.0f, flipY ? this.height : 0.0f);
                context.ConcatCTM(transform);

                this.image = context.ToImage();
            }
        }
Example #11
0
        public BitmapSource RenderImageSource(ILUT lut)
        {
            var render = false;

            if (_bitmap == null)
            {
                _pixels = new PinnedIntArray(ScaledData.Width * ScaledData.Height);
                render  = true;
            }

            if (_applyLut && lut != null && !lut.IsValid)
            {
                lut.Recalculate();
                render = true;
            }

            if (render)
            {
                ScaledData.Render((_applyLut ? lut : null), _pixels.Data);

                foreach (var overlay in _overlays)
                {
                    overlay.Render(_pixels.Data, ScaledData.Width, ScaledData.Height);
                }
            }

            using (
                var context = new CGBitmapContext(_pixels, ScaledWidth, ScaledHeight, 8, 4 * ScaledWidth,
                                                  CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedLast))
            {
                var transform = CGAffineTransform.MakeRotation((float)(_rotation * Math.PI / 180.0));
                transform.Scale(_flipX ? -1.0f : 1.0f, _flipY ? -1.0f : 1.0f);
                transform.Translate(_flipX ? ScaledWidth : 0.0f, _flipY ? ScaledHeight : 0.0f);
                context.ConcatCTM(transform);

                _bitmap = context.ToImage();
            }

            return(_bitmap);
        }
Example #12
0
        private byte[] RotateImage(UIImage image)
        {
            UIImage imageToReturn = null;

            if (image.Size.Height > image.Size.Width)
            {
                imageToReturn = image;
            }
            else
            {
                CGAffineTransform transform = CGAffineTransform.MakeIdentity();
                transform.Rotate(-(float)Math.PI / 2);
                transform.Translate(0, image.Size.Width);
                //now draw image
                using (var context = new CGBitmapContext(IntPtr.Zero,
                                                         (int)image.Size.Height,
                                                         (int)image.Size.Width,
                                                         image.CGImage.BitsPerComponent,
                                                         image.CGImage.BytesPerRow,
                                                         image.CGImage.ColorSpace,
                                                         image.CGImage.BitmapInfo))
                {
                    context.ConcatCTM(transform);
                    context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Width, (float)image.Size.Height)), image.CGImage);

                    using (var imageRef = context.ToImage())
                    {
                        imageToReturn = new UIImage(imageRef);
                    }
                }
            }

            using (NSData imageData = imageToReturn.AsPNG())
            {
                Byte[] byteArray = new Byte[imageData.Length];
                System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, byteArray, 0, Convert.ToInt32(imageData.Length));
                return(byteArray);
            }
        }
Example #13
0
        public static XIR.Image RemoteRepresentation(this CGPath cgPath)
        {
            // We add just a little padding to keep from clipping the drawings that lie on the bounds.
            var width  = (int)cgPath.PathBoundingBox.Width + 4 > 0 ? (int)cgPath.PathBoundingBox.Width + 4 : 200;
            var height = (int)cgPath.PathBoundingBox.Height + 4 > 0 ? (int)cgPath.PathBoundingBox.Height + 4 : 200;

            var bytesPerRow = width * 4;

            // We need to offset the image to keep from clipping the drawing.
            var offsetXZero = -cgPath.PathBoundingBox.X;
            var offsetYZero = -cgPath.PathBoundingBox.Y;

            // Create a transform to offset our drawing.
            var transform = CGAffineTransform.MakeIdentity();

            transform.Translate(offsetXZero + 1, offsetYZero + 1);

            using (var context = new CGBitmapContext(
                       IntPtr.Zero, width, height,
                       8, bytesPerRow, CGColorSpace.CreateDeviceRGB(),
                       CGImageAlphaInfo.PremultipliedFirst))
            {
                // Make sure we offset our drawing to keep it form clipping
                context.ConcatCTM(transform);

                context.SaveState();
                context.SetFillColor(brush.CGColor);
                context.AddPath(cgPath);
                context.FillPath();
                context.RestoreState();

                context.SetStrokeColor(pen.CGColor);
                context.SetLineWidth(1f);
                context.AddPath(cgPath);
                context.DrawPath(CGPathDrawingMode.Stroke);

                return(context.RemoteRepresentation());
            }
        }
Example #14
0
        public static UIImage FixOrientation(this UIImage image)
        {
            if (image.Orientation == UIImageOrientation.Up)
            {
                return(image);
            }

            var transform = CGAffineTransform.MakeIdentity();

            switch (image.Orientation)
            {
            case UIImageOrientation.Down:
            case UIImageOrientation.DownMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Width, image.Size.Height);
                transform = CGAffineTransform.Rotate(transform, (float)Math.PI);
                break;

            case UIImageOrientation.Left:
            case UIImageOrientation.LeftMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                transform = CGAffineTransform.Rotate(transform, (float)Math.PI / 2);
                break;

            case UIImageOrientation.Right:
            case UIImageOrientation.RightMirrored:
                transform = CGAffineTransform.Translate(transform, 0, image.Size.Height);
                transform = CGAffineTransform.Rotate(transform, -(float)Math.PI / 2);
                break;
            }

            switch (image.Orientation)
            {
            case UIImageOrientation.UpMirrored:
            case UIImageOrientation.DownMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                transform = CGAffineTransform.Scale(transform, -1, 1);
                break;

            case UIImageOrientation.LeftMirrored:
            case UIImageOrientation.RightMirrored:
                transform = CGAffineTransform.Translate(transform, image.Size.Height, 0);
                transform = CGAffineTransform.Scale(transform, -1, 1);
                break;
            }

            using (var cgImg = image.CGImage)
                using (var ctx = new CGBitmapContext(null, (nint)image.Size.Width, (nint)image.Size.Height, cgImg.BitsPerComponent, 0, cgImg.ColorSpace, cgImg.BitmapInfo))
                {
                    ctx.ConcatCTM(transform);

                    switch (image.Orientation)
                    {
                    case UIImageOrientation.Left:
                    case UIImageOrientation.LeftMirrored:
                    case UIImageOrientation.Right:
                    case UIImageOrientation.RightMirrored:
                        ctx.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), cgImg);
                        break;

                    default:
                        ctx.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), cgImg);
                        break;
                    }

                    using (var newCgImg = ctx.ToImage())
                    {
                        return(UIImage.FromImage(newCgImg));
                    }
                }
        }
Example #15
0
        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();
                    }
                }
            }
        }
Example #16
0
        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;
        }
Example #17
0
        public void GetData <T>(T[] data)
        {
            // TODO Causese AV on Device, but not simulator GetData<T>(0, null, data, 0, Width * Height);

            if (data == null)
            {
                throw new ArgumentException("data cannot be null");
            }

            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)
                {
                    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();
                    imageData  = Marshal.AllocHGlobal(height * width * 4);
                    context    = new CGBitmapContext(imageData, width, height, 8, 4 * width, colorSpace, CGImageAlphaInfo.PremultipliedLast);
                    colorSpace.Dispose();
                    break;

                case SurfaceFormat.Rgb32:
                    colorSpace = CGColorSpace.CreateDeviceRGB();
                    imageData  = Marshal.AllocHGlobal(height * width * 4);
                    context    = new CGBitmapContext(imageData, width, height, 8, 4 * width, colorSpace, CGImageAlphaInfo.NoneSkipLast);
                    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;
                }

                // Loop through and extract the data
                for (int y = 0; y < imageSize.Height; y++)
                {
                    for (int x = 0; x < imageSize.Width; x++)
                    {
                        var result = new Color(0, 0, 0, 0);

                        switch (pixelFormat)
                        {
                        case SurfaceFormat.Rgba32:                                  //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.Rgb32:                                  // kTexture2DPixelFormat_RGB565
                            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 = 255;
                            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;
                    }
                }

                context.Dispose();
                Marshal.FreeHGlobal(imageData);
            }
        }
Example #18
0
        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);
        }
Example #19
0
        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  = image.Width;
            imageSize.Height = image.Height;

            width  = image.Width;
            height = 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 = image.BitsPerComponent;
            bitsPerPixel     = 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.PremultipliedLast;
                }
            }
            else
            {
                premultiplied    = true;
                colorSpace       = CGColorSpace.CreateDeviceRGB();
                bitsPerComponent = 8;
                bitsPerPixel     = 32;
                bitmapInfo       = CGBitmapFlags.PremultipliedLast;
            }

            bytesPerRow = width * bitsPerPixel / bitsPerComponent;
            size        = bytesPerRow * height;

            bitmapBlock = Marshal.AllocHGlobal(size);
            bitmap      = new CGBitmapContext(bitmapBlock,
                                              image.Width, image.Width,
                                              bitsPerComponent,
                                              bytesPerRow,
                                              colorSpace,
                                              bitmapInfo);

            bitmap.ClearRect(new RectangleF(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 RectangleF(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, false, CGColorRenderingIntent.Default);

            colorSpace.Dispose();
            bitmap.Dispose();
        }
        UIImage FixOrientation(UIImage image)
        {
            if (image.Orientation == UIImageOrientation.Up)
            return image;

             CGAffineTransform transform = CGAffineTransform.MakeIdentity ();

             switch (image.Orientation)
             {
            case UIImageOrientation.Down:
            case UIImageOrientation.DownMirrored:
               transform = CGAffineTransform.Translate (transform, image.Size.Width, image.Size.Height);
               transform = CGAffineTransform.Rotate (transform, (nfloat)(Math.PI));
               break;
            case UIImageOrientation.Left:
            case UIImageOrientation.LeftMirrored:
               transform = CGAffineTransform.Translate (transform, image.Size.Width, 0);
               transform = CGAffineTransform.Rotate (transform, (nfloat)(Math.PI / 2));
               break;
            case UIImageOrientation.Right:
            case UIImageOrientation.RightMirrored:
               transform = CGAffineTransform.Translate (transform, 0, image.Size.Height);
               transform = CGAffineTransform.Rotate (transform, (nfloat)(-1 * Math.PI / 2));
               break;
            case UIImageOrientation.Up:
            case UIImageOrientation.UpMirrored:
               break;
             }

             switch (image.Orientation)
             {
            case UIImageOrientation.UpMirrored:
            case UIImageOrientation.DownMirrored:
               transform = CGAffineTransform.Translate (transform, image.Size.Width, 0);
               transform = CGAffineTransform.Scale (transform, -1, 1);
               break;
            case UIImageOrientation.LeftMirrored:
            case UIImageOrientation.RightMirrored:
               transform = CGAffineTransform.Translate (transform, image.Size.Height, 0);
               transform = CGAffineTransform.Scale (transform, -1, 1);
               break;
            case UIImageOrientation.Up:
            case UIImageOrientation.Down:
            case UIImageOrientation.Left:
            case UIImageOrientation.Right:
               break;
             }

             using (CGBitmapContext ctx = new CGBitmapContext (null, (nint)image.Size.Width, (nint)image.Size.Height, (nint)image.CGImage.BitsPerComponent, (nint)0,
                                         image.CGImage.ColorSpace, image.CGImage.BitmapInfo))
             {
            ctx.ConcatCTM (transform);
            switch (image.Orientation)
            {
               case UIImageOrientation.Left:
               case UIImageOrientation.LeftMirrored:
               case UIImageOrientation.Right:
               case UIImageOrientation.RightMirrored:
                  ctx.DrawImage (new CGRect (0, 0, image.Size.Height, image.Size.Width), image.CGImage);
                  break;
               default:
                  ctx.DrawImage (new CGRect (0, 0, image.Size.Width, image.Size.Height), image.CGImage);
                  break;
            }

            using (var cgImage = ctx.ToImage ())
            {
               return new UIImage (cgImage);
            }
             }
        }
Example #21
0
        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);
        }
Example #22
0
        /// <summary>
        /// Returns thumb image object for page 
        /// </summary>
        /// <param name="thumbContentSize">Thumb content size</param>
        /// <param name="pageNumber">Page number for what will created image object</param>
        /// <returns>Page image object</returns>
        private static UIImage GetThumbImage(float thumbContentSize, int pageNumber)
        {
            if ((pageNumber <= 0) || (pageNumber > PDFDocument.PageCount)) {
                return null;
            }

            // Calc page view size
            var pageSize = PageContentView.GetPageViewSize(pageNumber);
            if (pageSize.Width % 2 > 0) {
                pageSize.Width--;
            }
            if (pageSize.Height % 2 > 0) {
                pageSize.Height--;
            }

            // Calc target size
            var targetSize = new Size((int)pageSize.Width, (int)pageSize.Height);

            // Draw page on CGImage
            CGImage pageImage;
            using (CGColorSpace rgb = CGColorSpace.CreateDeviceRGB()) {
                using (var context = new CGBitmapContext(null, targetSize.Width, targetSize.Height, 8, 0, rgb, CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.NoneSkipFirst)) {
                    using (var pdfPage = PDFDocument.GetPage(pageNumber)) {
                        // Draw page on custom CGBitmap context
                        var thumbRect = new RectangleF(0.0f, 0.0f, targetSize.Width, targetSize.Height);
                        context.SetFillColor(1.0f, 1.0f, 1.0f, 1.0f);
                        context.FillRect(thumbRect);
                        context.ConcatCTM(pdfPage.GetDrawingTransform(CGPDFBox.Crop, thumbRect, 0, true));
                        context.SetRenderingIntent(CGColorRenderingIntent.Default);
                        context.InterpolationQuality = CGInterpolationQuality.Default;
                        context.DrawPDFPage(pdfPage);
                        // Create CGImage from custom CGBitmap context
                        pageImage = context.ToImage();
                    }
                }
            }
            return UIImage.FromImage(pageImage);
        }
Example #23
0
        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();
        }
Example #24
0
        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();
        }
Example #25
0
        //Create a Method to set orientation of image...
        private byte[] RotateImage(UIImage image)
        {
            UIImage imageToReturn = null;

            if (image.Orientation == UIImageOrientation.Up)
            {
                imageToReturn = image;
            }
            else
            {
                CGAffineTransform transform = CGAffineTransform.MakeIdentity();

                switch (image.Orientation)
                {
                case UIImageOrientation.Down:
                case UIImageOrientation.DownMirrored:
                    transform.Rotate((float)Math.PI);
                    transform.Translate(image.Size.Width, image.Size.Height);
                    break;

                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                    transform.Rotate((float)Math.PI / 2);
                    transform.Translate(image.Size.Width, 0);
                    break;

                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    transform.Rotate(-(float)Math.PI / 2);
                    transform.Translate(0, image.Size.Height);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.UpMirrored:
                    break;
                }

                switch (image.Orientation)
                {
                case UIImageOrientation.UpMirrored:
                case UIImageOrientation.DownMirrored:
                    transform.Translate(image.Size.Width, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.RightMirrored:
                    transform.Translate(image.Size.Height, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.Down:
                case UIImageOrientation.Left:
                case UIImageOrientation.Right:
                    break;
                }

                //now draw image
                using (var context = new CGBitmapContext(IntPtr.Zero,
                                                         (int)image.Size.Width,
                                                         (int)image.Size.Height,
                                                         image.CGImage.BitsPerComponent,
                                                         image.CGImage.BytesPerRow,
                                                         image.CGImage.ColorSpace,
                                                         image.CGImage.BitmapInfo))
                {
                    context.ConcatCTM(transform);
                    switch (image.Orientation)
                    {
                    case UIImageOrientation.Left:
                    case UIImageOrientation.LeftMirrored:
                    case UIImageOrientation.Right:
                    case UIImageOrientation.RightMirrored:
                        // Grr...
                        context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Height, (float)image.Size.Width)), image.CGImage);
                        break;

                    default:
                        context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Width, (float)image.Size.Height)), image.CGImage);
                        break;
                    }

                    using (var imageRef = context.ToImage())
                    {
                        imageToReturn = new UIImage(imageRef);
                    }
                }
            }

            using (NSData imageData = imageToReturn.AsJPEG())
            {
                Byte[] byteArray = new Byte[imageData.Length];
                System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, byteArray, 0, Convert.ToInt32(imageData.Length));
                return(byteArray);
            }
        }
		// Draws our animation path on the background image, just to show it
		protected void DrawPathAsBackground ()
		{
			// create our offscreen bitmap context
			var bitmapSize = new SizeF (View.Frame.Size);
			using (var context = new CGBitmapContext (
				       IntPtr.Zero,
				       (int)bitmapSize.Width, (int)bitmapSize.Height, 8,
				       (int)(4 * bitmapSize.Width), CGColorSpace.CreateDeviceRGB (),
				       CGImageAlphaInfo.PremultipliedFirst)) {
				
				// convert to View space
				var affineTransform = CGAffineTransform.MakeIdentity ();
				// invert the y axis
				affineTransform.Scale (1f, -1f);
				// move the y axis up
				affineTransform.Translate (0, View.Frame.Height);
				context.ConcatCTM (affineTransform);

				// actually draw the path
				context.AddPath (animationPath);
				context.SetStrokeColor (UIColor.LightGray.CGColor);
				context.SetLineWidth (3f);
				context.StrokePath ();
				
				// set what we've drawn as the backgound image
				backgroundImage.Image = UIImage.FromImage (context.ToImage());
			}
		}
Example #27
0
        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 Stream RotateImage(UIImage image, int compressionQuality, string pathExtension)
        {
            UIImage imageToReturn = null;

            if (image.Orientation == UIImageOrientation.Up)
            {
                imageToReturn = image;
            }
            else
            {
                var transform = CGAffineTransform.MakeIdentity();

                switch (image.Orientation)
                {
                case UIImageOrientation.Down:
                case UIImageOrientation.DownMirrored:
                    transform.Rotate((float)Math.PI);
                    transform.Translate(image.Size.Width, image.Size.Height);
                    break;

                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                    transform.Rotate((float)Math.PI / 2);
                    transform.Translate(image.Size.Width, 0);
                    break;

                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    transform.Rotate(-(float)Math.PI / 2);
                    transform.Translate(0, image.Size.Height);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.UpMirrored:
                    break;
                }

                switch (image.Orientation)
                {
                case UIImageOrientation.UpMirrored:
                case UIImageOrientation.DownMirrored:
                    transform.Translate(image.Size.Width, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.RightMirrored:
                    transform.Translate(image.Size.Height, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.Down:
                case UIImageOrientation.Left:
                case UIImageOrientation.Right:
                    break;
                }

                using var context = new CGBitmapContext(IntPtr.Zero,
                                                        (int)image.Size.Width,
                                                        (int)image.Size.Height,
                                                        image.CGImage.BitsPerComponent,
                                                        image.CGImage.BytesPerRow,
                                                        image.CGImage.ColorSpace,
                                                        image.CGImage.BitmapInfo);
                context.ConcatCTM(transform);
                switch (image.Orientation)
                {
                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    context.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), image.CGImage);
                    break;

                default:
                    context.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), image.CGImage);
                    break;
                }

                using var imageRef = context.ToImage();
                imageToReturn      = new UIImage(imageRef, 1, UIImageOrientation.Up);
            }

            pathExtension = pathExtension.ToLowerInvariant();
            var finalQuality = pathExtension == "jpg" ? (compressionQuality / 100f) : 0f;
            var imageData    = pathExtension == "jpg" ? imageToReturn.AsJPEG(finalQuality) : imageToReturn.AsPNG();

            //continue to move down quality , rare instances
            while (imageData == null && finalQuality > 0)
            {
                finalQuality -= 0.05f;
                imageData     = imageToReturn.AsJPEG(finalQuality);
            }

            if (imageData == null)
            {
                throw new NullReferenceException("Unable to convert image to jpeg, please ensure file exists or lower quality level");
            }

            var stream = new MemoryStream();

            imageData.AsStream().CopyTo(stream);
            stream.Position = 0;
            imageData.Dispose();
            image.Dispose();
            image = null;
            return(stream);
        }
Example #29
0
        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();
                    }
                }
            }
        }
Example #30
0
        static Texture2D FromUIImage(UIImage uiImage, string name)
        {
            All filter = All.Linear;

            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:
            Point logicalSize = new Point((int)uiImage.Size.Width, (int)uiImage.Size.Height);

            int pixelWidth = uiImage.CGImage.Width;
            int pixelHeight = uiImage.CGImage.Height;

            // Round up the target texture width and height to powers of two:
            int potWidth = pixelWidth;
            int 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));
            }

            lock(textureLoadBufferLockObject)
            {
                CreateTextureLoadBuffer();

                unsafe
                {
                    fixed(byte* data = textureLoadBuffer)
                    {
                        using(var colorSpace = CGColorSpace.CreateDeviceRGB())
                        using(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);

                            uint textureId = 0;
                            /*textureId = new uint[1];
                            textureId[0]= 0;
                            GL.GenTextures(1,textureId);*/
                            GL.GenTextures(1, ref textureId);
                            GL.BindTexture(All.Texture2D, textureId);
                            GL.TexParameter(All.Texture2D, All.TextureMinFilter, (int)filter);
                            GL.TexParameter(All.Texture2D, All.TextureMagFilter, (int)filter);
                            GL.TexImage2D(All.Texture2D, 0, (int)All.Rgba, (int)potWidth, (int)potHeight, 0, All.Rgba, All.UnsignedByte, new IntPtr(data));

                            return new Texture2D(logicalSize.X, logicalSize.Y,
                                    pixelWidth, pixelHeight, potWidth, potHeight,
                                    textureId, name);
                        }
                    }
                }
            }
        }
Example #31
0
        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.Color;
                }
                else
                {
                    pixelFormat = SurfaceFormat.Color;
                }
            }
            else
            {
                pixelFormat = SurfaceFormat.Alpha8;
            }

            imageSize = new Size(image.Width, image.Height);
            transform = CGAffineTransform.MakeIdentity();
            width     = imageSize.Width;

            // Take out the width and height adjustments for power of 2
            //  If not then GetData and SetData is messed up.

            // The Mac opengl version supports non power of 2 textures
            // so we do not have to make them so
//			if ((width != 1) && ((width & (width - 1)) != 0)) {
//				i = 1;
//				while ((sizeToFit ? 2 * i : i) < width)
//					i *= 2;
//				width = i;
//			}

            height = imageSize.Height;

            // The Mac opengl version supports non power of 2 textures
            // so we do not have to make them so
//			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;
//			}

            // I am going to take the following out right now to see how it reacts.  It seems to be causing
            // a few problems for people.  We may need to come up with another way to solve these issues as
            // one size is not fitting all.
//			float size = Math.Max(width,height);
//			if(size > 1024)
//			{
//				float ratio = 1024 / size;
//				width = (int)(width * ratio);
//				height = (int)(height * ratio);
//				transform = CGAffineTransform.MakeScale(ratio, ratio);
//				imageSize.Width = (int)(imageSize.Width * ratio);
//				imageSize.Height = (int)(imageSize.Height * ratio);;
//			}

            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 static UIImage CorrectImageRotation(UIImage image)
        {
            UIImage imageToReturn = null;

            if (image.Orientation == UIImageOrientation.Up)
            {
                imageToReturn = image;
            }
            else
            {
                var transform = CGAffineTransform.MakeIdentity();

                switch (image.Orientation)
                {
                case UIImageOrientation.Down:
                case UIImageOrientation.DownMirrored:
                    transform.Rotate((float)Math.PI);
                    transform.Translate(image.Size.Width, image.Size.Height);
                    break;

                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                    transform.Rotate((float)Math.PI / 2);
                    transform.Translate(image.Size.Width, 0);
                    break;

                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    transform.Rotate(-(float)Math.PI / 2);
                    transform.Translate(0, image.Size.Height);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.UpMirrored:
                    break;
                }

                switch (image.Orientation)
                {
                case UIImageOrientation.UpMirrored:
                case UIImageOrientation.DownMirrored:
                    transform.Translate(image.Size.Width, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.RightMirrored:
                    transform.Translate(image.Size.Height, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.Down:
                case UIImageOrientation.Left:
                case UIImageOrientation.Right:
                    break;
                }

                using var context = new CGBitmapContext(
                          IntPtr.Zero,
                          (int)image.Size.Width,
                          (int)image.Size.Height,
                          image.CGImage.BitsPerComponent,
                          image.CGImage.BytesPerRow,
                          image.CGImage.ColorSpace,
                          image.CGImage.BitmapInfo);

                context.ConcatCTM(transform);
                switch (image.Orientation)
                {
                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    context.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), image.CGImage);
                    break;

                default:
                    context.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), image.CGImage);
                    break;
                }

                using var imageRef = context.ToImage();
                imageToReturn      = new UIImage(imageRef, 1, UIImageOrientation.Up);
            }

            return(imageToReturn);
        }
Example #33
0
        public static Stream RotateImage(UIImage image)
        {
            UIImage imageToReturn = null;

            if (image.Orientation == UIImageOrientation.Up)
            {
                imageToReturn = image;
            }
            else
            {
                CGAffineTransform transform = CGAffineTransform.MakeIdentity();

                switch (image.Orientation)
                {
                case UIImageOrientation.Down:
                case UIImageOrientation.DownMirrored:
                    transform.Rotate((float)Math.PI);
                    transform.Translate(image.Size.Width, image.Size.Height);
                    break;

                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                    transform.Rotate((float)Math.PI / 2);
                    transform.Translate(image.Size.Width, 0);
                    break;

                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    transform.Rotate(-(float)Math.PI / 2);
                    transform.Translate(0, image.Size.Height);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.UpMirrored:
                    break;
                }

                switch (image.Orientation)
                {
                case UIImageOrientation.UpMirrored:
                case UIImageOrientation.DownMirrored:
                    transform.Translate(image.Size.Width, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.RightMirrored:
                    transform.Translate(image.Size.Height, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.Down:
                case UIImageOrientation.Left:
                case UIImageOrientation.Right:
                    break;
                }

                using (var context = new CGBitmapContext(IntPtr.Zero,
                                                         (int)image.Size.Width,
                                                         (int)image.Size.Height,
                                                         image.CGImage.BitsPerComponent,
                                                         image.CGImage.BytesPerRow,
                                                         image.CGImage.ColorSpace,
                                                         image.CGImage.BitmapInfo))
                {
                    context.ConcatCTM(transform);
                    switch (image.Orientation)
                    {
                    case UIImageOrientation.Left:
                    case UIImageOrientation.LeftMirrored:
                    case UIImageOrientation.Right:
                    case UIImageOrientation.RightMirrored:
                        context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Height, (float)image.Size.Width)), image.CGImage);
                        break;

                    default:
                        context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Width, (float)image.Size.Height)), image.CGImage);
                        break;
                    }

                    using (var imageRef = context.ToImage())
                    {
                        imageToReturn = new UIImage(imageRef);
                    }
                }
            }

            return(imageToReturn.AsJPEG().AsStream());
        }
            UIImage FixOrientation(UIImage image)
            {
                // It's portrait.
                if (image.Orientation == UIImageOrientation.Up)
                {
                    return(image);
                }

                var transform = CGAffineTransform.MakeIdentity();

                switch (image.Orientation)
                {
                case UIImageOrientation.Down:
                case UIImageOrientation.DownMirrored:
                    transform = CGAffineTransform.Translate(transform, image.Size.Width, image.Size.Height);
                    transform = CGAffineTransform.Rotate(transform, (nfloat)Math.PI);
                    break;

                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                    transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                    transform = CGAffineTransform.Rotate(transform, (nfloat)(Math.PI / 2));
                    break;

                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    transform = CGAffineTransform.Translate(transform, 0, image.Size.Height);
                    transform = CGAffineTransform.Rotate(transform, (nfloat)(-Math.PI / 2));
                    break;

                default: break;
                }

                switch (image.Orientation)
                {
                case UIImageOrientation.UpMirrored:
                case UIImageOrientation.DownMirrored:
                    transform = CGAffineTransform.Translate(transform, image.Size.Width, 0);
                    transform = CGAffineTransform.Scale(transform, -1, 1);
                    break;

                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.RightMirrored:
                    transform = CGAffineTransform.Translate(transform, image.Size.Height, 0);
                    transform = CGAffineTransform.Scale(transform, -1, 1);
                    break;

                default: break;
                }

                var ctx = new CGBitmapContext(IntPtr.Zero, (nint)image.Size.Width, (nint)image.Size.Height, image.CGImage.BitsPerComponent, 0,
                                              image.CGImage.ColorSpace, image.CGImage.BitmapInfo);

                ctx.ConcatCTM(transform);
                switch (image.Orientation)
                {
                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    ctx.DrawImage(new CGRect(0, 0, image.Size.Height, image.Size.Width), image.CGImage);
                    break;

                default:
                    ctx.DrawImage(new CGRect(0, 0, image.Size.Width, image.Size.Height), image.CGImage);
                    break;
                }

                var cgimg = ctx.ToImage();
                var img   = UIImage.FromImage(cgimg);

                ctx.Dispose();
                cgimg.Dispose();
                return(img);
            }
Example #35
0
        internal static void NativeDrawString(CGBitmapContext bitmapContext, string s, CTFont font, CCColor4B brush, RectangleF layoutRectangle)
        {
            if (font == null)
            {
                throw new ArgumentNullException("font");
            }

            if (s == null || s.Length == 0)
            {
                return;
            }

            bitmapContext.ConcatCTM(bitmapContext.GetCTM().Invert());

            // This is not needed here since the color is set in the attributed string.
            //bitmapContext.SetFillColor(brush.R/255f, brush.G/255f, brush.B/255f, brush.A/255f);

            // I think we only Fill the text with no Stroke surrounding
            //bitmapContext.SetTextDrawingMode(CGTextDrawingMode.Fill);

            var attributedString = buildAttributedString(s, font, brush);

            // Work out the geometry
            RectangleF insetBounds = layoutRectangle;

            PointF textPosition = new PointF(insetBounds.X,
                                             insetBounds.Y);

            float boundsWidth = insetBounds.Width;

            // Calculate the lines
            int start  = 0;
            int length = attributedString.Length;

            var typesetter = new CTTypesetter(attributedString);

            float baselineOffset = 0;

            // First we need to calculate the offset for Vertical Alignment if we
            // are using anything but Top
            if (vertical != CCVerticalTextAlignment.Top)
            {
                while (start < length)
                {
                    int count = typesetter.SuggestLineBreak(start, boundsWidth);
                    var line  = typesetter.GetLine(new NSRange(start, count));

                    // Create and initialize some values from the bounds.
                    float ascent;
                    float descent;
                    float leading;
                    line.GetTypographicBounds(out ascent, out descent, out leading);
                    baselineOffset += (float)Math.Ceiling(ascent + descent + leading + 1);                      // +1 matches best to CTFramesetter's behavior
                    line.Dispose();
                    start += count;
                }
            }

            start = 0;

            while (start < length && textPosition.Y < insetBounds.Bottom)
            {
                // Now we ask the typesetter to break off a line for us.
                // This also will take into account line feeds embedded in the text.
                //  Example: "This is text \n with a line feed embedded inside it"
                int count = typesetter.SuggestLineBreak(start, boundsWidth);
                var line  = typesetter.GetLine(new NSRange(start, count));

                // Create and initialize some values from the bounds.
                float ascent;
                float descent;
                float leading;
                line.GetTypographicBounds(out ascent, out descent, out leading);

                // Calculate the string format if need be
                var penFlushness = 0.0f;

                if (horizontal == CCTextAlignment.Right)
                {
                    penFlushness = (float)line.GetPenOffsetForFlush(1.0f, boundsWidth);
                }
                else if (horizontal == CCTextAlignment.Center)
                {
                    penFlushness = (float)line.GetPenOffsetForFlush(0.5f, boundsWidth);
                }

                // initialize our Text Matrix or we could get trash in here
                var textMatrix = CGAffineTransform.MakeIdentity();

                if (vertical == CCVerticalTextAlignment.Top)
                {
                    textMatrix.Translate(penFlushness, insetBounds.Height - textPosition.Y - (float)Math.Floor(ascent - 1));
                }
                if (vertical == CCVerticalTextAlignment.Center)
                {
                    textMatrix.Translate(penFlushness, ((insetBounds.Height / 2) + (baselineOffset / 2)) - textPosition.Y - (float)Math.Floor(ascent - 1));
                }
                if (vertical == CCVerticalTextAlignment.Bottom)
                {
                    textMatrix.Translate(penFlushness, baselineOffset - textPosition.Y - (float)Math.Floor(ascent - 1));
                }

                // Set our matrix
                bitmapContext.TextMatrix = textMatrix;

                // and draw the line
                line.Draw(bitmapContext);

                // Move the index beyond the line break.
                start          += count;
                textPosition.Y += (float)Math.Ceiling(ascent + descent + leading + 1);                 // +1 matches best to CTFramesetter's behavior
                line.Dispose();
            }
        }
        public static Stream RotateImage(UIImage image)
        {
            UIImage imageToReturn = null;

            if (image.Orientation == UIImageOrientation.Up)
            {
                imageToReturn = image;
            }
            else
            {
                CGAffineTransform transform = CGAffineTransform.MakeIdentity();

                switch (image.Orientation)
                {
                case UIImageOrientation.Down:
                case UIImageOrientation.DownMirrored:
                    transform.Rotate((float)Math.PI);
                    transform.Translate(image.Size.Width, image.Size.Height);
                    break;

                case UIImageOrientation.Left:
                case UIImageOrientation.LeftMirrored:
                    transform.Rotate((float)Math.PI / 2);
                    transform.Translate(image.Size.Width, 0);
                    break;

                case UIImageOrientation.Right:
                case UIImageOrientation.RightMirrored:
                    transform.Rotate(-(float)Math.PI / 2);
                    transform.Translate(0, image.Size.Height);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.UpMirrored:
                    break;
                }

                switch (image.Orientation)
                {
                case UIImageOrientation.UpMirrored:
                case UIImageOrientation.DownMirrored:
                    transform.Translate(image.Size.Width, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.LeftMirrored:
                case UIImageOrientation.RightMirrored:
                    transform.Translate(image.Size.Height, 0);
                    transform.Scale(-1, 1);
                    break;

                case UIImageOrientation.Up:
                case UIImageOrientation.Down:
                case UIImageOrientation.Left:
                case UIImageOrientation.Right:
                    break;
                }

                using (var context = new CGBitmapContext(IntPtr.Zero,
                                                         (int)image.Size.Width,
                                                         (int)image.Size.Height,
                                                         image.CGImage.BitsPerComponent,
                                                         image.CGImage.BytesPerRow,
                                                         image.CGImage.ColorSpace,
                                                         image.CGImage.BitmapInfo))
                {
                    context.ConcatCTM(transform);
                    switch (image.Orientation)
                    {
                    case UIImageOrientation.Left:
                    case UIImageOrientation.LeftMirrored:
                    case UIImageOrientation.Right:
                    case UIImageOrientation.RightMirrored:
                        context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Height, (float)image.Size.Width)), image.CGImage);
                        break;

                    default:
                        context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Width, (float)image.Size.Height)), image.CGImage);
                        break;
                    }

                    using (var imageRef = context.ToImage())
                    {
                        imageToReturn = new UIImage(imageRef);
                    }
                }
            }

            var finalQuality = 1.0f;
            var imageData    = image.AsJPEG(finalQuality);

            //continue to move down quality , rare instances
            while (imageData == null && finalQuality > 0)
            {
                finalQuality -= 0.05f;
                imageData     = image.AsJPEG(finalQuality);
            }

            if (imageData == null)
            {
                throw new NullReferenceException("Unable to convert image to jpeg, please ensure file exists or lower quality level");
            }

            var stream = imageData.AsStream();

            imageData.Dispose();
            return(stream);
        }
Example #37
0
        static string RenderPoint(XIR.Point point)
        {
            var base64 = string.Empty;

            var pointSize = new CGSize(8, 8);
            var rectangle = new CGRect(0, 0, 100, 100);

            var measure = CGSize.Empty;

            var line = GetLabel(string.Format("({0:0.########}, {1:0.###########})", point.X, point.Y), out measure);

            if (measure.Width > rectangle.Width)
            {
                rectangle.Size = new CGSize(measure.Width, measure.Width);
            }

            int width  = (int)rectangle.Width;
            int height = (int)rectangle.Height;

            var bytesPerRow = 4 * width;

            using (var context = new CGBitmapContext(
                       IntPtr.Zero, width, height,
                       8, bytesPerRow, CGColorSpace.CreateDeviceRGB(),
                       CGImageAlphaInfo.PremultipliedFirst))
            {
                context.SetFillColor(BackgroundColor.CGColor);
                context.FillRect(rectangle);


                context.SetFillColor(pen.CGColor);
                var centerX = rectangle.GetMidX() - pointSize.Width / 2;
                var centerY = rectangle.GetMidY() - pointSize.Height / 2;
                context.FillEllipseInRect(new CGRect(centerX, centerY, pointSize.Width, pointSize.Height));

                context.ConcatCTM(context.GetCTM().Invert());
                var matrix = new CGAffineTransform(
                    1, 0, 0, -1, 0, height);

                context.ConcatCTM(matrix);
                var textMatrix = new CGAffineTransform(
                    1, 0, 0, -1, 0, 0);

                context.TextMatrix = textMatrix;

                context.TextPosition = new CGPoint(rectangle.GetMidX() - measure.Width / 2, rectangle.GetMidY() - (measure.Height * 2));

                line.Draw(context);
                line.Dispose();

                line = GetSubLabel("x, y", out measure);
                context.TextPosition = new CGPoint(rectangle.GetMidX() - measure.Width / 2, rectangle.GetMidY() - (measure.Height));

                line.Draw(context);
                line.Dispose();

                var bitmap = new NSBitmapImageRep(context.ToImage());

                var data = bitmap.RepresentationUsingTypeProperties(NSBitmapImageFileType.Png);
                base64 = data.GetBase64EncodedString(NSDataBase64EncodingOptions.None);
            }

            return(String.Format(
                       "<figure>" +
                       "<figcaption>" +
                       "Point: " +
                       "<span class='var'>X</span> = <span class='value'>{0:0.########}</span>, " +
                       "<span class='var'>Y</span> = <span class='value'>{1:0.########}</span>" +
                       "</figcaption>" +
                       "<img width='{2}' height='{3}' src='data:image/png;base64,{4}' />" +
                       "</figure>",
                       point.X, point.Y,
                       (int)rectangle.Width,
                       (int)rectangle.Height,
                       base64
                       ));
        }
Example #38
0
        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();
            }
        }
Example #39
0
        static string RenderSize(XIR.Size size)
        {
            var base64 = string.Empty;

            // We want the absolute values of the size
            var workSize = new CGSize(Math.Abs(size.Width), Math.Abs(size.Height));

            // This is our scale factor for output
            var dstSize = new CGSize(50, 50);

            // Define our Height label variables
            var numHeightLabelBounds = CGSize.Empty;
            var heightLabelBounds    = CGSize.Empty;
            var heightBounds         = CGSize.Empty;

            // Obtain our label lines and bounding boxes of the labels
            var numHeightLine = GetLabel(string.Format("{0:0.########}", size.Height), out numHeightLabelBounds);
            var heightLine    = GetSubLabel("Height", out heightLabelBounds);

            heightBounds.Width  = NMath.Max(numHeightLabelBounds.Width, heightLabelBounds.Width);
            heightBounds.Height = NMath.Max(numHeightLabelBounds.Height, heightLabelBounds.Height);


            // Define our Width label variables
            var numWidthLabelBounds = CGSize.Empty;
            var widthLabelBounds    = CGSize.Empty;
            var widthBounds         = CGSize.Empty;

            // Obtain our label lines and bound boxes of the labels
            var numWidthLine = GetLabel(string.Format("{0:0.########}", size.Width), out numWidthLabelBounds);
            var widthLine    = GetSubLabel("Width", out widthLabelBounds);

            widthBounds.Width  = NMath.Max(numWidthLabelBounds.Width, widthLabelBounds.Width);
            widthBounds.Height = NMath.Max(numWidthLabelBounds.Height, widthLabelBounds.Height);

            // Calculate our scale based on our destination size
            var ratio = 1f;

            if (workSize.Width > workSize.Height)
            {
                ratio          = (float)workSize.Height / (float)workSize.Width;
                dstSize.Height = (int)(dstSize.Height * ratio);
            }
            else
            {
                ratio         = (float)workSize.Width / (float)workSize.Height;
                dstSize.Width = (int)(dstSize.Width * ratio);
            }

            // Make sure we at least have something to draw if the values are very small
            dstSize.Width  = NMath.Max(dstSize.Width, 4f);
            dstSize.Height = NMath.Max(dstSize.Height, 4f);

            // Define graphic element sizes and offsets
            const int   lineWidth       = 2;
            const float capSize         = 8f;
            const float vCapIndent      = 3f;
            const float separationSpace = 2f;

            var extraBoundingSpaceWidth  = (widthBounds.Width + separationSpace) * 2;
            var extraBoundingSpaceHeight = (heightBounds.Height + separationSpace) * 2;

            int width  = (int)(dstSize.Width + lineWidth + capSize + vCapIndent + extraBoundingSpaceWidth);
            int height = (int)(dstSize.Height + lineWidth + capSize + extraBoundingSpaceHeight);

            var bytesPerRow = 4 * width;

            using (var context = new CGBitmapContext(
                       IntPtr.Zero, width, height,
                       8, bytesPerRow, CGColorSpace.CreateDeviceRGB(),
                       CGImageAlphaInfo.PremultipliedFirst))
            {
                // Clear the context with our background color
                context.SetFillColor(BackgroundColor.CGColor);
                context.FillRect(new CGRect(0, 0, width, height));

                // Setup our matrices so our 0,0 is top left corner.  Just makes it easier to layout
                context.ConcatCTM(context.GetCTM().Invert());
                var matrix = new CGAffineTransform(
                    1, 0, 0, -1, 0, height);

                context.ConcatCTM(matrix);

                context.SetStrokeColor(pen.CGColor);
                context.SetLineWidth(lineWidth);

                context.SaveState();

                // We need to offset the drawing of our size segment rulers leaving room for labels
                var xOffSet = heightBounds.Width;
                var yOffset = (height - extraBoundingSpaceHeight) / 2f - dstSize.Height / 2f;

                context.TranslateCTM(xOffSet, yOffset);

                // Draw the Height segment ruler
                var vCapCenter = vCapIndent + (capSize / 2f);

                context.AddLines(new CGPoint[] { new CGPoint(vCapIndent, 1), new CGPoint(vCapIndent + capSize, 1),
                                                 new CGPoint(vCapCenter, 1), new CGPoint(vCapCenter, dstSize.Height),
                                                 new CGPoint(vCapIndent, dstSize.Height), new CGPoint(vCapIndent + capSize, dstSize.Height), });


                // Draw the Width segment ruler
                var hCapIndent  = vCapIndent + capSize + separationSpace;
                var hCapOffsetY = dstSize.Height;
                var hCapCenter  = hCapOffsetY + (capSize / 2f);
                context.AddLines(new CGPoint[] { new CGPoint(hCapIndent, hCapOffsetY), new CGPoint(hCapIndent, hCapOffsetY + capSize),
                                                 new CGPoint(hCapIndent, hCapCenter), new CGPoint(hCapIndent + dstSize.Width, hCapCenter),
                                                 new CGPoint(hCapIndent + dstSize.Width, hCapOffsetY), new CGPoint(hCapIndent + dstSize.Width, hCapOffsetY + capSize), });

                context.StrokePath();

                context.RestoreState();

                // Setup our text matrix
                var textMatrix = new CGAffineTransform(
                    1, 0, 0, -1, 0, 0);

                context.TextMatrix = textMatrix;


                // Draw the Height label
                context.TextPosition = new CGPoint(heightBounds.Width / 2 - numHeightLabelBounds.Width / 2, height / 2 - heightBounds.Height / 2);
                numHeightLine.Draw(context);

                context.TextPosition = new CGPoint(heightBounds.Width / 2 - heightLabelBounds.Width / 2, height / 2 + heightBounds.Height / 2);
                heightLine.Draw(context);


                // Draw the Width label
                var widthOffsetX = heightBounds.Width - separationSpace + dstSize.Width / 2;
                context.TextPosition = new CGPoint(widthOffsetX + (widthBounds.Width / 2 - numWidthLabelBounds.Width / 2), height - widthBounds.Height - 2);
                numWidthLine.Draw(context);

                context.TextPosition = new CGPoint(widthOffsetX + (widthBounds.Width / 2 - widthLabelBounds.Width / 2), height - widthLabelBounds.Height / 2);
                widthLine.Draw(context);

                // Get rid of our lines
                numHeightLine.Dispose();
                heightLine.Dispose();

                numWidthLine.Dispose();
                widthLine.Dispose();

                // Convert to base64 for display
                var bitmap = new NSBitmapImageRep(context.ToImage());

                var data = bitmap.RepresentationUsingTypeProperties(NSBitmapImageFileType.Png);
                base64 = data.GetBase64EncodedString(NSDataBase64EncodingOptions.None);
            }

            return(String.Format("" +
                                 "<figure>" +
                                 "<figcaption>" +
                                 "Size: " +
                                 "<span class='var'>Width</span> = <span class='value'>{0:0.########}</span>, " +
                                 "<span class='var'>Height</span> = <span class='value'>{1:0.########}</span>" +
                                 "</figcaption>" +
                                 "<img width='{2}' height='{3}' src='data:image/png;base64,{4}' />" +
                                 "</figure>",
                                 size.Width, size.Height,
                                 (int)width,
                                 (int)height,
                                 base64
                                 ));
        }