Пример #1
0
        protected override void init(Stream stream, bool flip, Loader.LoadedCallbackMethod loadedCallback)
        {
            try
            {
                using (var image = NSImage.FromStream(stream))
                {
                    var rep = image.Representations()[0];
                    int width = rep.PixelsWide;
                    int height = rep.PixelsHigh;
                    Mipmaps = new Mipmap[1];
                    Size = new Size2(width, height);

                    var data = new byte[width * height * 4];
                    var emptyRect = RectangleF.Empty;
                    using (CGContext imageContext = new CGBitmapContext(data, width, height, 8, width*4, CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedLast))
                    using (var cgImage = image.AsCGImage(ref emptyRect, null, null))
                    {
                        imageContext.DrawImage(new RectangleF(0, 0, width, height), cgImage);

                        Mipmaps[0] = new Mipmap(data, width, height, 1, 4);
                        if (flip) Mipmaps[0].FlipVertical();
                    }
                }
            }
            catch (Exception e)
            {
                FailedToLoad = true;
                Loader.AddLoadableException(e);
                if (loadedCallback != null) loadedCallback(this, false);
                return;
            }

            Loaded = true;
            if (loadedCallback != null) loadedCallback(this, true);
        }
Пример #2
0
 void GetImagaDataFromPath (string path)
 {
         int width, height;
         NSImage src;
         CGImage image;
         CGContext context = null;
         RectangleF rect = RectangleF.Empty;
         
         data = new byte[TEXTURE_WIDTH * TEXTURE_HEIGHT * 4];
         
         src = new NSImage (path);
         
         image = src.AsCGImage (ref rect, null, null);
         width = image.Width;
         height = image.Height;
         
         CGImageAlphaInfo ai = CGImageAlphaInfo.PremultipliedLast;
         
         context = new CGBitmapContext (data, width, height, 8, 4 * width, image.ColorSpace, ai);
         
         // Core Graphics referential is upside-down compared to OpenGL referential
         // Flip the Core Graphics context here
         // An alternative is to use flipped OpenGL texture coordinates when drawing textures
         context.TranslateCTM (0, height);
         context.ScaleCTM (1, -1);
         
         // Set the blend mode to copy before drawing since the previous contents of memory aren't used. 
         // This avoids unnecessary blending.
         context.SetBlendMode (CGBlendMode.Copy);
         
         context.DrawImage (new RectangleF (0, 0, width, height), image);
 }
Пример #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.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);
        }
Пример #4
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);	
		}
Пример #5
0
        private void MakeSureWeHaveAnAlphaChannel()
        {
            // Initialize our prmultiplied tables.
            if (!ConversionHelpers.sTablesInitialized)
                ConversionHelpers.CalculateTables ();

            var alphaInfo = NativeCGImage.AlphaInfo;
            var hasAlpha = ((alphaInfo == CGImageAlphaInfo.PremultipliedLast)
                            || (alphaInfo == CGImageAlphaInfo.PremultipliedFirst)
                            || (alphaInfo == CGImageAlphaInfo.Last)
                            || (alphaInfo == CGImageAlphaInfo.First) ? true : false);

            if (cachedContext != null && cachedContext.Handle != IntPtr.Zero)
            {
                return;
            }

            // set our pixel format
            pixelFormat = PixelFormat.Format32bppArgb;
            // and mark the rawformat as from memory
            rawFormat = ImageFormat.MemoryBmp;

            //format = GetBestSupportedFormat (pixelFormat);
            cachedContext = CreateCompatibleBitmapContext (NativeCGImage.Width, NativeCGImage.Height, pixelFormat);

            // Fill our pixel data with the actual image information
            cachedContext.DrawImage (new RectangleF (0, 0, NativeCGImage.Width, NativeCGImage.Height), NativeCGImage);

            // Dispose of the prevous image that is allocated.
            NativeCGImage.Dispose ();

            // Get a reference to the pixel data
            bitmapBlock = cachedContext.Data;
            int size = cachedContext.BytesPerRow * cachedContext.Height;
            var provider = new CGDataProvider (cachedContext.Data, size, true);

            // Get the image from the bitmap context.
            //NativeCGImage = bitmapContext.ToImage ();
            CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB();
            NativeCGImage = new CGImage (cachedContext.Width, cachedContext.Height, cachedContext.BitsPerComponent,
                                         cachedContext.BitsPerPixel, cachedContext.BytesPerRow,
                                         colorSpace,
                                         cachedContext.AlphaInfo,
                                         provider, null, true, CGColorRenderingIntent.Default);
            colorSpace.Dispose ();
        }
Пример #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
		void GetImagaDataFromPath (string path)
		{
			NSImage src;
			CGImage image;
			CGContext context = null;

			src = new NSImage (path);

			image = src.AsCGImage (RectangleF.Empty, null, null);
			width = image.Width;
			height = image.Height;

			int bytesPerRow = image.BytesPerRow;
			int bitsPerPixel = image.BitsPerPixel;
			int bitsPerComponent = image.BitsPerComponent;

			data = new byte[bytesPerRow * height * 4];
			
			CGImageAlphaInfo ai = CGImageAlphaInfo.PremultipliedLast;
			CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB();
			
			context = new CGBitmapContext (data, width, height, 8, 4 * width, colorSpace, ai);

			// Core Graphics referential is upside-down compared to OpenGL referential
			// Flip the Core Graphics context here
			// An alternative is to use flipped OpenGL texture coordinates when drawing textures
			context.TranslateCTM (0, height);
			context.ScaleCTM (1, -1);

			// Set the blend mode to copy before drawing since the previous contents of memory aren't used. 
			// This avoids unnecessary blending.
			context.SetBlendMode (CGBlendMode.Copy);

			context.DrawImage (new RectangleF (0, 0, width, height), image);
		}