public static void EncodeImage(this d2.Bitmap target, ImageFormat imageFormat, Stream outputStream)
        {
            var width  = target.PixelSize.Width;
            var height = target.PixelSize.Height;

            var wicBitmap = new wic.Bitmap(DXGraphicsService.FactoryImaging, width, height,
                                           wic.PixelFormat.Format32bppBGR, wic.BitmapCreateCacheOption.CacheOnLoad);
            var renderTargetProperties = new d2.RenderTargetProperties(d2.RenderTargetType.Default,
                                                                       new d2.PixelFormat(Format.Unknown,
                                                                                          d2.AlphaMode.Unknown), 0, 0,
                                                                       d2.RenderTargetUsage.None,
                                                                       d2.FeatureLevel.Level_DEFAULT);
            var d2DRenderTarget = new d2.WicRenderTarget(target.Factory, wicBitmap, renderTargetProperties);

            d2DRenderTarget.BeginDraw();
            d2DRenderTarget.Clear(global::SharpDX.Color.Transparent);
            d2DRenderTarget.DrawBitmap(target, 1, d2.BitmapInterpolationMode.Linear);
            d2DRenderTarget.EndDraw();

            var stream = new wic.WICStream(DXGraphicsService.FactoryImaging, outputStream);

            // Initialize a Jpeg encoder with this stream
            var encoder = new wic.BitmapEncoder(DXGraphicsService.FactoryImaging, GetImageFormat(imageFormat));

            encoder.Initialize(stream);

            // Create a Frame encoder
            var bitmapFrameEncode = new wic.BitmapFrameEncode(encoder);

            bitmapFrameEncode.Initialize();
            bitmapFrameEncode.SetSize(width, height);
            Guid pixelFormatGuid = wic.PixelFormat.FormatDontCare;

            bitmapFrameEncode.SetPixelFormat(ref pixelFormatGuid);
            bitmapFrameEncode.WriteSource(wicBitmap);

            bitmapFrameEncode.Commit();
            encoder.Commit();

            bitmapFrameEncode.Dispose();
            encoder.Dispose();
            stream.Dispose();

            d2DRenderTarget.Dispose();
            wicBitmap.Dispose();
        }
예제 #2
0
        internal CCTexture2D CreateTextSprite(string text, CCFontDefinition textDefinition)
        {
            if (string.IsNullOrEmpty(text))
                return new CCTexture2D();

            int imageWidth;
            int imageHeight;
            var textDef = textDefinition;
            var contentScaleFactorWidth = CCLabel.DefaultTexelToContentSizeRatios.Width;
            var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height;
            textDef.FontSize *= contentScaleFactorWidth;
            textDef.Dimensions.Width *= contentScaleFactorWidth;
            textDef.Dimensions.Height *= contentScaleFactorHeight;

            var font = CreateFont(textDef.FontName, textDef.FontSize);
            if (font == null)
            {
                CCLog.Log("Can not create font {0} with size {1}.", textDef.FontName, textDef.FontSize);
                return new CCTexture2D();
            }


            var _currentFontSizeEm = textDef.FontSize;
            var _currentDIP = ConvertPointSizeToDIP(_currentFontSizeEm);

            // color
            var foregroundColor = Color4.White;

            // alignment
            var horizontalAlignment = textDef.Alignment;
            var verticleAlignement = textDef.LineAlignment;

            var textAlign = (CCTextAlignment.Right == horizontalAlignment) ? TextAlignment.Trailing
                : (CCTextAlignment.Center == horizontalAlignment) ? TextAlignment.Center
                : TextAlignment.Leading;

            var paragraphAlign = (CCVerticalTextAlignment.Bottom == vertAlignment) ? ParagraphAlignment.Far
                : (CCVerticalTextAlignment.Center == vertAlignment) ? ParagraphAlignment.Center
                : ParagraphAlignment.Near;

            // LineBreak
            var lineBreak = (CCLabelLineBreak.Character == textDef.LineBreak) ? WordWrapping.Wrap
                : (CCLabelLineBreak.Word == textDef.LineBreak) ? WordWrapping.Wrap
                : WordWrapping.NoWrap;

            // LineBreak
            // TODO: Find a way to specify the type of line breaking if possible.

            var dimensions = new CCSize(textDef.Dimensions.Width, textDef.Dimensions.Height);

            var layoutAvailable = true;
            if (dimensions.Width <= 0)
            {
                dimensions.Width = 8388608;
                layoutAvailable = false;
            }

            if (dimensions.Height <= 0)
            {
                dimensions.Height = 8388608;
                layoutAvailable = false;
            }

            var fontName = font.FontFamily.FamilyNames.GetString(0);
            var textFormat = new TextFormat(FactoryDWrite, fontName,
                _currentFontCollection, FontWeight.Regular, FontStyle.Normal, FontStretch.Normal, _currentDIP);

            textFormat.TextAlignment = textAlign;
            textFormat.ParagraphAlignment = paragraphAlign;

            var textLayout = new TextLayout(FactoryDWrite, text, textFormat, dimensions.Width, dimensions.Height);

            var boundingRect = new RectangleF();

            // Loop through all the lines so we can find our drawing offsets
            var textMetrics = textLayout.Metrics;
            var lineCount = textMetrics.LineCount;

            // early out if something went wrong somewhere and nothing is to be drawn
            if (lineCount == 0)
                return new CCTexture2D();

            // Fill out the bounding rect width and height so we can calculate the yOffset later if needed
            boundingRect.X = 0; 
            boundingRect.Y = 0; 
            boundingRect.Width = textMetrics.Width;
            boundingRect.Height = textMetrics.Height;

            if (!layoutAvailable)
            {
                if (dimensions.Width == 8388608)
                {
                    dimensions.Width = boundingRect.Width;
                }
                if (dimensions.Height == 8388608)
                {
                    dimensions.Height = boundingRect.Height;
                }
            }

            imageWidth = (int)dimensions.Width;
            imageHeight = (int)dimensions.Height;

            // Recreate our layout based on calculated dimensions so that we can draw the text correctly
            // in our image when Alignment is not Left.
            if (textAlign != TextAlignment.Leading)
            {
                textLayout.MaxWidth = dimensions.Width;
                textLayout.MaxHeight = dimensions.Height;
            }

            // Line alignment
            var yOffset = (CCVerticalTextAlignment.Bottom == verticleAlignement
                || boundingRect.Bottom >= dimensions.Height) ? dimensions.Height - boundingRect.Bottom  // align to bottom
                : (CCVerticalTextAlignment.Top == verticleAlignement) ? 0                    // align to top
                : (imageHeight - boundingRect.Bottom) * 0.5f;                                   // align to center


            SharpDX.WIC.Bitmap sharpBitmap = null;
            WicRenderTarget sharpRenderTarget = null;
            SolidColorBrush solidBrush = null;

            try
            {
                // Select our pixel format
                var pixelFormat = SharpDX.WIC.PixelFormat.Format32bppPRGBA;

                // create our backing bitmap
                sharpBitmap = new SharpDX.WIC.Bitmap(FactoryImaging, imageWidth, imageHeight, pixelFormat, BitmapCreateCacheOption.CacheOnLoad);

                // Create the render target that we will draw to
                sharpRenderTarget = new WicRenderTarget(Factory2D, sharpBitmap, new RenderTargetProperties());
                // Create our brush to actually draw with
                solidBrush = new SolidColorBrush(sharpRenderTarget, foregroundColor);

                // Begin the drawing
                sharpRenderTarget.BeginDraw();

                if (textDefinition.isShouldAntialias)
                    sharpRenderTarget.AntialiasMode = AntialiasMode.Aliased;

                // Clear it
                sharpRenderTarget.Clear(TransparentColor);

                // Draw the text to the bitmap
                sharpRenderTarget.DrawTextLayout(new Vector2(boundingRect.X, yOffset), textLayout, solidBrush);

                // End our drawing which will commit the rendertarget to the bitmap
                sharpRenderTarget.EndDraw();

                // Debugging purposes
                //var s = "Label4";
                //SaveToFile(@"C:\Xamarin\" + s + ".png", _bitmap, _renderTarget);

                // The following code creates a .png stream in memory of our Bitmap and uses it to create our Textue2D
                Texture2D tex = null;

                using (var memStream = new MemoryStream())
                {
                    using (var encoder = new PngBitmapEncoder(FactoryImaging, memStream))
                    using (var frameEncoder = new BitmapFrameEncode(encoder))
                    {
                        frameEncoder.Initialize();
                        frameEncoder.WriteSource(sharpBitmap);
                        frameEncoder.Commit();
                        encoder.Commit();
                    }
                    // Create the Texture2D from the png stream
                    tex = Texture2D.FromStream(CCDrawManager.SharedDrawManager.XnaGraphicsDevice, memStream);
                }

                // Return our new CCTexture2D created from the Texture2D which will have our text drawn on it.
                return new CCTexture2D(tex);
            }
            catch (Exception exc)
            {
                CCLog.Log("CCLabel-Windows: Unable to create the backing image of our text.  Message: {0}", exc.StackTrace);
            }
            finally
            {
                if (sharpBitmap != null)
                {
                    sharpBitmap.Dispose();
                    sharpBitmap = null;
                }

                if (sharpRenderTarget != null)
                {
                    sharpRenderTarget.Dispose();
                    sharpRenderTarget = null;
                }

                if (solidBrush != null)
                {
                    solidBrush.Dispose();
                    solidBrush = null;
                }

                if (textFormat != null)
                {
                    textFormat.Dispose();
                    textFormat = null;
                }

                if (textLayout != null)
                {
                    textLayout.Dispose();
                    textLayout = null;
                }
            }

            // If we have reached here then something has gone wrong.
            return new CCTexture2D();
        }