private static IntSize2 getTextureSize(String texturePath)
        {
            try
            {
                using (Stream stream = VirtualFileSystem.Instance.openStream(texturePath, Engine.Resources.FileMode.Open)) //Probably not the best idea to directly access vfs here
                {
                    int width, height;
                    if (texturePath.EndsWith(PagedImage.FileExtension, StringComparison.OrdinalIgnoreCase))
                    {
                        using (PagedImage pagedImage = new PagedImage())
                        {
                            pagedImage.loadInfoOnly(stream);
                            width  = pagedImage.Width;
                            height = pagedImage.Height;
                        }
                    }
                    else
                    {
                        ImageUtility.GetImageInfo(stream, out width, out height);
                    }
                    return(new IntSize2(width, height));
                }
            }
            catch (Exception ex)
            {
            }

            return(new IntSize2(2048, 2048)); //Hardcoded size for now.
        }
Exemple #2
0
        /// <summary>
        /// Create a paged image from a FreeImageBitmap instance, note that this function is destructive
        /// to the passed in FreeImageBitmap since it will resize it while creating all the mip levels
        /// for the paged image. However, you will still need to dispose the image you pass in, this class
        /// makes a copy while destroying the image, but does not take ownership of the original.
        /// </summary>
        /// <param name="image">The image to extract pages from.</param>
        /// <param name="pageSize">The size of the pages to extract.</param>
        public static void fromBitmap(FreeImageBitmap image, int pageSize, int padding, Stream stream, ImageType imageType, int maxSize, bool lossless, FREE_IMAGE_FILTER filter, ImagePageSizeStrategy pageSizeStrategy, Action <FreeImageBitmap> afterResize = null)
        {
            stream.Seek(HeaderSize, SeekOrigin.Begin); //Leave some space for the header

            if (image.Width > maxSize)
            {
                Logging.Log.Info("Image size {0} was too large, resizing to {1}", image.Width, maxSize);
                pageSizeStrategy.rescaleImage(image, new Size(maxSize, maxSize), filter);
            }

            PagedImage            pagedImage = new PagedImage();
            int                   padding2x  = padding * 2;
            FREE_IMAGE_FORMAT     outputFormat;
            FREE_IMAGE_SAVE_FLAGS saveFlags = FREE_IMAGE_SAVE_FLAGS.DEFAULT;

            switch (imageType)
            {
            default:
            case ImageType.PNG:
                outputFormat = FREE_IMAGE_FORMAT.FIF_PNG;
                break;

            case ImageType.WEBP:
                outputFormat = FREE_IMAGE_FORMAT.FIF_WEBP;
                if (lossless)
                {
                    saveFlags = FREE_IMAGE_SAVE_FLAGS.WEBP_LOSSLESS;
                }
                else
                {
                    saveFlags = (FREE_IMAGE_SAVE_FLAGS)90;
                }
                break;
            }

            //Kind of weird, ogre and freeimage are backwards from one another in terms of scanline 0 being the top or bottom
            //This easily fixes the math below by just flipping the image first. Note that pages must be flipped back over because
            //of this when they are saved.
            image.RotateFlip(RotateFlipType.RotateNoneFlipY);

            pagedImage.numImages  = 0;
            pagedImage.imageType  = (int)imageType;
            pagedImage.imageXSize = image.Width;
            pagedImage.imageYSize = image.Height;
            pagedImage.pageSize   = pageSize;
            if (pagedImage.imageXSize != pagedImage.imageYSize)
            {
                throw new InvalidDataException("Image must be a square");
            }

            int mipLevelCount = 0;
            int numPages      = 0;

            for (int i = pagedImage.imageXSize; i >= pageSize; i >>= 1)
            {
                ++mipLevelCount;
                int pagesForMip = i / pageSize;
                numPages += pagesForMip * pagesForMip;
            }
            pagedImage.pages      = new List <ImageInfo>(numPages);
            pagedImage.mipIndices = new List <MipIndexInfo>(mipLevelCount);

            IntSize2 fullPageSize = new IntSize2(pageSize + padding2x, pageSize + padding2x);

            for (int mip = 0; mip < mipLevelCount; ++mip)
            {
                //Setup mip level
                if (mip != 0)
                {
                    pageSizeStrategy.rescaleImage(image, new Size(image.Width >> 1, image.Height >> 1), filter);
                    if (afterResize != null)
                    {
                        //Flip so external functions aren't confused
                        image.RotateFlip(RotateFlipType.RotateNoneFlipY);
                        afterResize(image);
                        //Flip back for correct math
                        image.RotateFlip(RotateFlipType.RotateNoneFlipY);
                    }
                }
                int size = image.Width / pageSize;
                pagedImage.mipIndices.Add(new MipIndexInfo(pagedImage.numImages, size));
                pageSizeStrategy.extractPage(image, padding, stream, pagedImage, pageSize, fullPageSize, size, outputFormat, saveFlags);
            }

            //Write half size mip
            int      halfPageSize   = pageSize >> 1;
            IntSize2 halfSizePadded = new IntSize2(halfPageSize + padding2x, halfPageSize + padding2x);

            pageSizeStrategy.rescaleImage(image, new Size(image.Width >> 1, image.Height >> 1), filter);
            pageSizeStrategy.extractPage(image, padding, stream, pagedImage, halfPageSize, halfSizePadded, 1, outputFormat, saveFlags);

            pagedImage.indexStart = (int)stream.Position;

            using (BinaryWriter sw = new BinaryWriter(stream, EncodingShim.Default, true))
            {
                foreach (var imageInfo in pagedImage.pages)
                {
                    imageInfo.write(sw);
                }

                //Go back to header reserved space
                sw.BaseStream.Seek(0, SeekOrigin.Begin);
                sw.Write(MagicNumber);
                sw.Write(pagedImage.numImages);
                sw.Write(pagedImage.imageType);
                sw.Write(pagedImage.imageXSize);
                sw.Write(pagedImage.imageYSize);
                sw.Write(pagedImage.pageSize);
                sw.Write(pagedImage.indexStart);
            }
        }