Example #1
0
        private ImageSource assembleTiles(String tileDirectory, int tileW, int tileH, string instanceMarker, string extension, out int width, out int height, string name, int imageWidth, int imageHeight, double scale, CropTransform cropAfterRotating, Model.RotateTransform rotate, String outputDirectory)
        {
            // Now that we have our tiles on the hard drive, piece them back together to display to the user

            // WPF assemblage is too memory-intensive (as far as I can tell). Shell out to GDI+
            TileHelper.Concatenater helper = new TileHelper.Concatenater();
            string fileName = helper.ConcatenateTiles(imageHeight, imageWidth, tileH, tileW, tileDirectory, instanceMarker, extension, name, scale, cropAfterRotating, rotate, outputDirectory);
            // Now that the files are concatenated, save off the matching xml
            string xmlFileName = String.Format("{0}.{1}.{2}.xml", _container.Name, instanceMarker, extension);
            saveXmlFile(xmlFileName);
            // I think I need to save off a small version to display in the UI

            DrawingVisual dv = new DrawingVisual();
            using (DrawingContext ctx = dv.RenderOpen())
            {
                PngBitmapDecoder d = new PngBitmapDecoder(new Uri(fileName), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                ctx.DrawImage(d.Frames[0], new Rect(0, 0, (int)d.Frames[0].Width, (int)d.Frames[0].Height));
            }
            // Scale it back down for UI
            double displayScale = (_container.DisplayScale <= 0 ? 0.1 : _container.DisplayScale);
            width = (int)(dv.ContentBounds.Width * displayScale);
            height = (int)(dv.ContentBounds.Height * displayScale);
            ScaleTransform scaleTrans = new ScaleTransform(displayScale, displayScale);
            dv.Transform = scaleTrans;
            _rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
            _rtb.Render(dv);

            // Now that we're done with the tiles, clean up
            if (System.Configuration.ConfigurationSettings.AppSettings["deleteTiles"].ToLower() == "true")
            {
                helper.deleteTiles(tileDirectory, instanceMarker, extension);
            }

            return (ImageSource)_rtb;
        }
Example #2
0
        public string ConcatenateTiles(int height, int width, int tileHeight, int tileWidth, string tileDirectoryFullPath, string key, string extension, string name, double scale, CropTransform cropAfterRotating, RotateTransform rotate, string outputDirectory)
        {
            if (String.IsNullOrEmpty(tileDirectoryFullPath) || String.IsNullOrEmpty(key))
            {
                return String.Empty;
            }
            else
            {
                const int WIDTH_POSITION = 1;
                const int HEIGHT_POSITION = 0;
                int posW = 0;
                int posH = 0;

                Bitmap b = new Bitmap(width, height);
                Graphics g = Graphics.FromImage(b);

                DirectoryInfo di = new DirectoryInfo(tileDirectoryFullPath);

                foreach (FileInfo fi in di.GetFiles())
                {
                    string[] positions = fi.Name.Split('.');
                    if (positions.Length > WIDTH_POSITION)
                    {
                        if (int.TryParse(positions[WIDTH_POSITION], out posW) &&
                            int.TryParse(positions[HEIGHT_POSITION], out posH) &&
                            fi.Name.Contains(key) &&
                            fi.Name.EndsWith(extension))
                        {
                            Image i = Image.FromFile(fi.FullName);
                            g.DrawImage(i, new Rectangle(posW * tileWidth, posH * tileHeight, i.Width, i.Height));
                            i = null;
                        }
                    }
                }

                string fileName = String.Format("{0}\\{1}.{2}.nonrotated.{3}", outputDirectory, name, key, extension);
                b.Save(fileName);
                g.Dispose();
                runGC();

                if (rotate != null)
                {

                    if (rotate.Angle != 0 && rotate.Apply)
                    {
                        // Rotation code

                        Bitmap b1 = new Bitmap(width, height);
                        Graphics g1 = Graphics.FromImage(b1);

                        Image rotatedImage = Image.FromFile(fileName);
                        float rotateAngle = (float)rotate.Angle;
                        // Adjust the rotate angle to match GDI+ goofy idea of angle
                        if (rotateAngle > 0 && rotateAngle < 360)
                            rotateAngle -= 180;

                        g1.RotateTransform(rotateAngle);
                        g1.TranslateTransform(width / 2, height / 2, System.Drawing.Drawing2D.MatrixOrder.Append);
                        // TODO: implement cropping here
                        float floatScale = (float)scale;
                        g1.DrawImage(rotatedImage, width / 2, height / 2, -width, -height);

                        fileName = String.Format("{0}\\{1}.{2}.rotated.{3}", outputDirectory, name, key, extension);

                        b1.Save(fileName);
                        g1.Dispose();
                        runGC();

                        if (cropAfterRotating != null)
                        {

                            if (cropAfterRotating.Width > 0 && cropAfterRotating.Height > 0 && cropAfterRotating.Apply)
                            {
                                float cropWidthVector = (float)cropAfterRotating.Width * floatScale;
                                float cropHeightVector = (float)cropAfterRotating.Height * floatScale;
                                Bitmap b2 = (Bitmap)Image.FromFile(fileName);
                                Bitmap cropped = new Bitmap((int)cropWidthVector, (int)cropHeightVector);
                                float cropX = (float)cropAfterRotating.X * floatScale;
                                float cropY = (float)cropAfterRotating.Y * floatScale;

                                Graphics g2 = Graphics.FromImage(cropped);

                                g2.DrawImage(b2, new Rectangle(0, 0, cropped.Width, cropped.Height), cropX, cropY, cropped.Width, cropped.Height, GraphicsUnit.Pixel);

                                g2.Dispose();
                                runGC();

                                fileName = String.Format("{0}\\{1}.{2}.cropped.{3}", outputDirectory, name, key, extension);
                                cropped.Save(fileName);
                            }
                        }
                    }
                }

                return fileName;
            }
        }
Example #3
0
        private ImageSource tileImage(DrawingVisual drawingVisual, double scale, out int width, out int height, bool saveToDisk, string name, CropTransform cropBeforeRotating, CropTransform cropAfterRotating, Model.RotateTransform rotate)
        {
            // We want to break the image into tiles
            // So I need to loop horitzontally and then vertically, saving the images as I go
            // I can come up with a naming convention so they can be put back together again, maybe using the positions of the tiles
            // Then I can reassemble the image, hopefully saving on memory versus calling Render() on the whole thing
            bool willCrop = false;
            if (cropBeforeRotating != null)
            {
                willCrop = (cropBeforeRotating.Height > 0 && cropBeforeRotating.Width > 0 && cropBeforeRotating.Apply);
            }

            String tileDirectory = System.Configuration.ConfigurationSettings.AppSettings["TileDirectory"];
            String outputDirectory = System.Configuration.ConfigurationSettings.AppSettings["OutputDirectory"];
            String fileName = String.Empty;
            String ticks = DateTime.Now.Ticks.ToString();
            if (!Directory.Exists(tileDirectory))
            {
                Directory.CreateDirectory(tileDirectory);
            }

            const String EXTENSION = "png";
            const int DEFAULT_H = 1000;
            const int DEFAULT_W = 1000;
            int remainderW = 0;
            int remainderH = 0;
            int offsetW = 0;
            int offsetH = 0;
            int sizeW = 0;
            int sizeH = 0;
            int posW = 0;
            int posH = 0;

            // If we are going to crop let's do it here
            if (willCrop)
            {
                offsetW = (int)(cropBeforeRotating.X * scale);
                offsetH = (int)(cropBeforeRotating.Y * scale);
                width = offsetW + (int)(cropBeforeRotating.Width * scale);
                height = offsetH + (int)(cropBeforeRotating.Height * scale);
            }
            else
            {
                if (_container.Transforms.CropBeforeRendering != null)
                {
                    if (_container.Transforms.CropBeforeRendering.Apply)
                    {
                        width = (int)(_container.Transforms.CropBeforeRendering.Width * scale);
                        height = (int)(_container.Transforms.CropBeforeRendering.Height * scale);
                    }
                    else
                    {
                        width = (int)(drawingVisual.ContentBounds.Width * scale);
                        height = (int)(drawingVisual.ContentBounds.Height * scale);
                    }
                }
                else
                {
                    width = (int)(drawingVisual.ContentBounds.Width * scale);
                    height = (int)(drawingVisual.ContentBounds.Height * scale);
                }
            }

            // test the remaining width and height
            // if >= the default amount, then leave at default
            // if < the default amount, set H or W to the remainder

            while (offsetH < height)
            {
                remainderH = height - offsetH;
                sizeH = (remainderH < DEFAULT_H ? remainderH : DEFAULT_H);

                while (offsetW < width)
                {
                    remainderW = width - offsetW;
                    sizeW = (remainderW < DEFAULT_W ? remainderW : DEFAULT_W);

                    drawingVisual.Offset = new Vector(offsetW * -1, offsetH * -1);
                    _rtb = new RenderTargetBitmap(sizeW, sizeH, 96, 96, PixelFormats.Pbgra32);
                    _rtb.Render(drawingVisual);
                    fileName = String.Format("{0}\\{1}.{2}.{3}.{4}", tileDirectory, posH.ToString(), posW.ToString(), ticks, EXTENSION);
                    offsetW += DEFAULT_W;
                    posW++;
                    saveImage(fileName);
                }

                if (willCrop)
                {
                    offsetW = (int)(cropBeforeRotating.X * scale);
                }
                else
                {
                    offsetW = 0;
                }
                remainderW = 0;
                posW = 0;

                offsetH += DEFAULT_H;
                posH++;
            }

            if (willCrop)
            {
                height = (int)(cropBeforeRotating.Height * scale);
                width = (int)(cropBeforeRotating.Width * scale);
            }

            return assembleTiles(tileDirectory, DEFAULT_H, DEFAULT_W, ticks, EXTENSION, out width, out height, name, width, height, scale, cropAfterRotating, rotate, outputDirectory);
        }