internal static CGBitmapContext CreateBitmap (int width, int height)  //, PixelFormat format)
		{
			int bitsPerComponent, bytesPerRow;
			CGColorSpace colorSpace;
			CGBitmapFlags bitmapInfo;
			//			bool premultiplied = false;
			int bitsPerPixel = 0;

			// Don't forget to set the Image width and height for size.
			imageSize.Width = width;
			imageSize.Height = height;

			colorSpace = CGColorSpace.CreateDeviceRGB ();
			bitsPerComponent = 8;
			bitsPerPixel = 32;
			bitmapInfo = CGBitmapFlags.PremultipliedLast;

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

			bitmapBlock = Marshal.AllocHGlobal (size);
			var bitmapContext = new CGBitmapContext (bitmapBlock, 
			                                     width, height, 
			                                     bitsPerComponent, 
			                                     bytesPerRow,
			                                     colorSpace,
			                                     bitmapInfo);

			// This works for now but we need to look into initializing the memory area itself
			bitmapContext.ClearRect (new CGRect (0,0,width,height));

			return bitmapContext;

		}
Пример #2
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;
            //			}

            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);
        }
Пример #3
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);	
		}
Пример #4
0
        private CGBitmapContext CreateCompatibleBitmapContext(int width, int height, PixelFormat pixelFormat)
        {
            int bitsPerComponent, bytesPerRow;
            CGColorSpace colorSpace;
            CGImageAlphaInfo alphaInfo;
            bool premultiplied = false;
            int bitsPerPixel = 0;

            // CoreGraphics only supports a few options so we have to make do with what we have
            // https://developer.apple.com/library/mac/qa/qa1037/_index.html
            switch (pixelFormat)
            {
            case PixelFormat.Format32bppPArgb:
            case PixelFormat.DontCare:
                premultiplied = true;
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                alphaInfo = CGImageAlphaInfo.PremultipliedLast;
                break;
            case PixelFormat.Format32bppArgb:
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                alphaInfo = CGImageAlphaInfo.PremultipliedLast;
                break;
            case PixelFormat.Format32bppRgb:
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                alphaInfo = CGImageAlphaInfo.PremultipliedLast;
                break;
            case PixelFormat.Format24bppRgb:
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                alphaInfo = CGImageAlphaInfo.PremultipliedLast;
                break;
            default:
                throw new Exception ("Format not supported: " + pixelFormat);
            }

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

            var bitmapBlock = Marshal.AllocHGlobal (size);
            var bitmap = new CGBitmapContext (bitmapBlock,
                                              width, height,
                                              bitsPerComponent,
                                              bytesPerRow,
                                              colorSpace,
                                              alphaInfo);

            bitmap.ClearRect (new RectangleF (0,0,width,height));

            //colorSpace.Dispose ();

            return bitmap;
        }
Пример #5
0
        public Bitmap(int width, int height, PixelFormat format)
        {
            imageTransform = new CGAffineTransform(1, 0, 0, -1, 0, height);

            int bitsPerComponent, bytesPerRow;
            CGColorSpace colorSpace;
            CGBitmapFlags bitmapInfo;
            bool premultiplied = false;
            int bitsPerPixel = 0;

            pixelFormat = format;

            // Don't forget to set the Image width and height for size.
            imageSize.Width = width;
            imageSize.Height = height;

            switch (format){
            case PixelFormat.Format32bppPArgb:
            case PixelFormat.DontCare:
                premultiplied = true;
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                bitmapInfo = CGBitmapFlags.PremultipliedFirst;
                break;
            case PixelFormat.Format32bppArgb:
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                bitmapInfo = CGBitmapFlags.PremultipliedFirst;
                break;
            case PixelFormat.Format32bppRgb:
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                bitmapInfo = CGBitmapFlags.NoneSkipLast;
                break;
            case PixelFormat.Format24bppRgb:
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                bitmapInfo = CGBitmapFlags.NoneSkipLast;
                break;
            default:
                throw new Exception ("Format not supported: " + format);
            }
            bytesPerRow = width * bitsPerPixel/bitsPerComponent;
            int size = bytesPerRow * height;

            bitmapBlock = Marshal.AllocHGlobal (size);
            var bitmap = new CGBitmapContext (bitmapBlock,
                                          width, height,
                                          bitsPerComponent,
                                          bytesPerRow,
                                          colorSpace,
                                          bitmapInfo);
            // This works for now but we need to look into initializing the memory area itself
            // TODO: Look at what we should do if the image does not have alpha channel
            bitmap.ClearRect (new RectangleF (0,0,width,height));

            var provider = new CGDataProvider (bitmapBlock, size, true);
            NativeCGImage = new CGImage (width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, bitmapInfo, provider, null, false, CGColorRenderingIntent.Default);

            dpiWidth = dpiHeight = ConversionHelpers.MS_DPI;
            physicalDimension.Width = width;
            physicalDimension.Height = height;

            // The physical size may be off on certain implementations.  For instance the dpiWidth and dpiHeight
            // are read using integers in core graphics but in windows it is a float.
            // For example:
            // coregraphics dpiWidth = 24 as integer
            // windows dpiWidth = 24.999935 as float
            // this gives a few pixels difference when calculating the physical size.
            // 256 * 96 / 24 = 1024
            // 256 * 96 / 24.999935 = 983.04
            //
            // https://bugzilla.xamarin.com/show_bug.cgi?id=14365
            // PR: https://github.com/mono/maccore/pull/57
            //

            physicalSize = new SizeF (physicalDimension.Width, physicalDimension.Height);
            physicalSize.Width *= ConversionHelpers.MS_DPI / dpiWidth;
            physicalSize.Height *= ConversionHelpers.MS_DPI / dpiHeight;

            rawFormat = ImageFormat.MemoryBmp;
            pixelFormat = format;
        }
Пример #6
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.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 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, true, image.RenderingIntent);

            colorSpace.Dispose();
            bitmap.Dispose();
        }
Пример #7
0
        public Bitmap(int width, int height, PixelFormat format)
        {
            int bitsPerComponent, bytesPerRow;
            CGColorSpace colorSpace;
            CGBitmapFlags bitmapInfo;
            bool premultiplied = false;
            int bitsPerPixel = 0;

            // Don't forget to set the Image width and height for size.
            imageSize.Width = width;
            imageSize.Height = height;

            switch (format){
            case PixelFormat.Format32bppPArgb:
                premultiplied = true;
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                bitmapInfo = CGBitmapFlags.PremultipliedFirst;
                break;
            case PixelFormat.Format32bppArgb:
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                bitmapInfo = CGBitmapFlags.PremultipliedFirst;
                break;
            case PixelFormat.Format32bppRgb:
                colorSpace = CGColorSpace.CreateDeviceRGB ();
                bitsPerComponent = 8;
                bitsPerPixel = 32;
                bitmapInfo = CGBitmapFlags.None;
                break;
            default:
                throw new Exception ("Format not supported: " + format);
            }
            bytesPerRow = width * bitsPerPixel/bitsPerComponent;
            int size = bytesPerRow * height;

            bitmapBlock = Marshal.AllocHGlobal (size);
            var bitmap = new CGBitmapContext (bitmapBlock,
                                          width, height,
                                          bitsPerComponent,
                                          bytesPerRow,
                                          colorSpace,
                                          CGImageAlphaInfo.PremultipliedLast);
            // This works for now but we need to look into initializing the memory area itself
            // TODO: Look at what we should do if the image does not have alpha channel
            bitmap.ClearRect (new RectangleF (0,0,width,height));

            var provider = new CGDataProvider (bitmapBlock, size, true);
            NativeCGImage = new CGImage (width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, bitmapInfo, provider, null, false, CGColorRenderingIntent.Default);
        }