private void writeSimpleDiffuseSprite(MaterialDescription description, MaterialRepository repo) { String diffuseSrc = getSourceFullPath(description.DiffuseMapName); if (!imageNeedsCompression(diffuseSrc)) { return; } String diffuseDest = getDestBasePath(description.DiffuseMapName); String normalDest = getDestBasePath(description.NormalMapName); String normalTmp = getTempPath(description.NormalMapName); using (FreeImageBitmap diffuseMap = FreeImageBitmap.FromFile(diffuseSrc)) { using (FreeImageBitmap normalMap = new FreeImageBitmap(diffuseMap.Width, diffuseMap.Height, FreeImageAPI.PixelFormat.Format32bppArgb)) { normalMap.FillBackground(new RGBQUAD(new FreeImageAPI.Color() { R = 0x80, G = 0x80, B = 0, A = 255 })); using (FreeImageBitmap combined = createImageFromChannels(normalMap, Channel.Red, normalMap, Channel.Green, diffuseMap, Channel.Alpha)) { saveImage(combined, normalTmp, TempFileImageFormat); compressCompositeNormalMap(diffuseSrc, normalTmp, normalDest, description); deleteFile(normalTmp); } } } Log.Info("Compressing diffuse map {0} directly", description.DiffuseMapName); compressDiffuseMap(diffuseSrc, diffuseDest, description); }
public static void Create(DmiImage dmi, string path) { var builder = new StringBuilder("# BEGIN DMI\n"); builder.Append("version = 4.0\n"); builder.Append("\twidth = " + dmi.StateWidth + "\n"); builder.Append("\theight = " + dmi.StateHeight + "\n"); var totalImages = dmi.States.Sum(x => x.GetFrames().Sum(y => y.GetImages().Count)); var xY = Math.Min(10, totalImages); var totalWidth = (dmi.StateWidth * xY); var totalHeight = dmi.StateHeight * (int)Math.Ceiling(totalImages / (float)xY); int pixelX = 0; int pixelY = totalHeight - 1; var img = new FreeImageBitmap(totalWidth, totalHeight, PixelFormat.Format32bppPArgb); img.FillBackground(Color.FromArgb(0, 0, 0, 0)); foreach (var state in dmi.States) { builder.AppendFormat("state = \"{0}\"\n", state.Name); builder.AppendFormat("\tdirs = {0}\n", state.Dir); builder.AppendFormat("\tframes = {0}\n", state.Frames); if (state.HasDelay) { builder.AppendFormat("\tdelay = {0}\n", state.GetDelayString); } if (state.Rewind > 0) { builder.AppendFormat("\trewind = {0}\n", state.Rewind); } foreach (var frame in state.GetFrames()) { foreach (var image in frame.GetImages()) { for (int x = 0; x < dmi.StateWidth; x++) { for (int y = 0; y < dmi.StateHeight; y++) { img.SetPixel(pixelX + x, pixelY - y, image.Bitmap.GetPixel(x, y)); } } pixelX += dmi.StateWidth; if (pixelX >= totalWidth) { pixelY -= dmi.StateHeight; pixelX = 0; } } } } builder.AppendLine("# END DMI"); if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } img.Save(path, FREE_IMAGE_FORMAT.FIF_PNG, FREE_IMAGE_SAVE_FLAGS.PNG_Z_DEFAULT_COMPRESSION); // Work around because FREEIMAGE saves metatags as unicode. AddMetadata(path, "Description", builder.ToString()); }
private IEnumerable <IdleStatus> createRender(int finalWidth, int finalHeight, int aaMode, bool showWatermark, bool transparentBG, Engine.Color backColor, Camera cloneCamera, Vector3 position, Vector3 lookAt, float minNearDistance, float nearPlaneWorld, float nearFarLength, ImageRendererProperties properties, Action <FreeImageBitmap> renderingCompletedCallback) { FreeImageBitmap bitmap = null; OgreSceneManager sceneManager = controller.CurrentScene.getDefaultSubScene().getSimElementManager <OgreSceneManager>(); if (sceneManager != null) { bool doGridRender; int backBufferWidth; int backBufferHeight; using (TexturePtr texture = createOgreTexture(finalWidth, finalHeight, aaMode, out doGridRender, out backBufferWidth, out backBufferHeight)) { if (texture != null) { using (HardwarePixelBufferSharedPtr pixelBuffer = texture.Value.getBuffer()) { RenderTexture renderTexture = pixelBuffer.Value.getRenderTarget(); Camera camera = sceneManager.SceneManager.createCamera("__PictureCamera"); camera.setLodBias(cloneCamera.getLodBias()); camera.setUseRenderingDistance(cloneCamera.getUseRenderingDistance()); camera.setNearClipDistance(cloneCamera.getNearClipDistance()); camera.setFarClipDistance(cloneCamera.getFarClipDistance()); camera.setPolygonMode(cloneCamera.getPolygonMode()); camera.setRenderingDistance(cloneCamera.getRenderingDistance()); camera.setProjectionType(cloneCamera.getProjectionType()); camera.setFOVy(cloneCamera.getFOVy()); camera.setAutoAspectRatio(false); camera.setAspectRatio((float)finalWidth / finalHeight); SceneNode node = sceneManager.SceneManager.createSceneNode("__PictureCameraNode"); node.attachObject(camera); node.setPosition(position); sceneManager.SceneManager.getRootSceneNode().addChild(node); camera.lookAt(lookAt); Viewport viewport = renderTexture.addViewport(camera, 1, 0.0f, 0.0f, 1.0f, 1.0f); if (properties.UseIncludePoint) { Matrix4x4 viewMatrix = camera.getViewMatrix(); Matrix4x4 projectionMatrix = camera.getProjectionMatrix(); float aspect = camera.getAspectRatio(); float fovy = camera.getFOVy() * 0.5f; float distance = SceneViewWindow.computeOffsetToIncludePoint(viewMatrix, projectionMatrix, properties.IncludePoint, aspect, fovy); Vector3 direction = (position - lookAt).normalized(); node.setPosition(position - (direction * distance)); camera.lookAt(lookAt); } if (transparentBG) { backColor.a = 0.0f; } ViewportBackground bgViewport = null; if (background != null) { bgViewport = new ViewportBackground("ImageRenderer", 0, background, renderTexture, false); bgViewport.BackgroundColor = backColor; bgViewport.Camera.setAutoAspectRatio(false); bgViewport.Camera.setAspectRatio((float)finalWidth / finalHeight); } viewport.setBackgroundColor(backColor); viewport.setOverlaysEnabled(false); viewport.setClearEveryFrame(false); if (properties.CustomizeCameraPosition != null) { properties.CustomizeCameraPosition(camera, viewport); } float near = CameraPositioner.computeNearClipDistance(camera.getDerivedPosition().length(), minNearDistance, nearPlaneWorld); camera.setNearClipDistance(near); camera.setFarClipDistance(near + nearFarLength); if (doGridRender) { IEnumerable <IdleStatus> process = gridRender(finalWidth * aaMode, finalHeight * aaMode, backBufferWidth, backBufferHeight, aaMode, renderTexture, camera, bgViewport != null ? bgViewport.Camera : null, transparentBG, backColor, (product) => { bitmap = product; }); foreach (IdleStatus idleStatus in process) { yield return(idleStatus); } } else { bitmap = simpleRender(backBufferWidth, backBufferHeight, aaMode, transparentBG, backColor, renderTexture); } if (showWatermark && LoadLogo != null) { using (FreeImageBitmap logo = LoadLogo()) { float imageFinalHeight = bitmap.Height * 0.0447f; float scale = imageFinalHeight / logo.Height; float imageFinalWidth = logo.Width * scale; if (imageFinalWidth > bitmap.Width) { imageFinalWidth = bitmap.Width; scale = imageFinalWidth / logo.Width; imageFinalHeight = logo.Height * scale; } logo.Rescale((int)imageFinalWidth, (int)imageFinalHeight, FREE_IMAGE_FILTER.FILTER_BILINEAR); //Have to composite the logo image first. using (FreeImageBitmap fullImageCorner = bitmap.Copy(0, bitmap.Height - (int)imageFinalHeight, (int)imageFinalWidth, bitmap.Height)) { fullImageCorner.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP); logo.Composite(false, null, fullImageCorner); } bitmap.Paste(logo, 0, bitmap.Height - (int)imageFinalHeight, int.MaxValue); } } renderTexture.destroyViewport(viewport); if (bgViewport != null) { bgViewport.Dispose(); } sceneManager.SceneManager.getRootSceneNode().removeChild(node); sceneManager.SceneManager.destroySceneNode(node); sceneManager.SceneManager.destroyCamera(camera); TextureManager.getInstance().remove(texture); } } else { //An error making the render texture. Log it and return the error image. Log.Error("Could not render image. Returning placeholder image. Reason: Could not create valid render to texture target."); bitmap = new FreeImageBitmap(finalWidth, finalHeight); bitmap.FillBackground(new RGBQUAD() { rgbRed = 255 }); } } } renderingCompletedCallback(bitmap); yield break; }
public static void Create(DmiImage dmi, string path) { var builder = new StringBuilder("# BEGIN DMI\n"); builder.Append("version = 4.0\n"); builder.Append("\twidth = " + dmi.StateWidth + "\n"); builder.Append("\theight = " + dmi.StateHeight + "\n"); var totalImages = dmi.States.Sum(x => x.GetFrames().Sum(y => y.GetImages().Count)); var xY = Math.Min(10, totalImages); var totalWidth = (dmi.StateWidth * xY); var totalHeight = dmi.StateHeight * (int)Math.Ceiling(totalImages / (float)xY); int pixelX = 0; int pixelY = totalHeight - 1; var img = new FreeImageBitmap(totalWidth, totalHeight, PixelFormat.Format32bppPArgb); img.FillBackground(Color.FromArgb(0, 0, 0, 0)); foreach (var state in dmi.States) { builder.AppendFormat("state = \"{0}\"\n", state.Name); builder.AppendFormat("\tdirs = {0}\n", state.Dir); builder.AppendFormat("\tframes = {0}\n", state.Frames); if (state.HasDelay) builder.AppendFormat("\tdelay = {0}\n", state.GetDelayString); if (state.Rewind > 0) builder.AppendFormat("\trewind = {0}\n", state.Rewind); foreach (var frame in state.GetFrames()) { foreach (var image in frame.GetImages()) { for (int x = 0; x < dmi.StateWidth; x++) { for (int y = 0; y < dmi.StateHeight; y++) { img.SetPixel(pixelX + x, pixelY - y, image.Bitmap.GetPixel(x, y)); } } pixelX += dmi.StateWidth; if (pixelX >= totalWidth) { pixelY -= dmi.StateHeight; pixelX = 0; } } } } builder.AppendLine("# END DMI"); if (!Directory.Exists(Path.GetDirectoryName(path))) Directory.CreateDirectory(Path.GetDirectoryName(path)); img.Save(path, FREE_IMAGE_FORMAT.FIF_PNG, FREE_IMAGE_SAVE_FLAGS.PNG_Z_DEFAULT_COMPRESSION); // Work around because FREEIMAGE saves metatags as unicode. AddMetadata(path, "Description", builder.ToString()); }
public void updateThumbnail(bool forceUpdateSceneThumb = false) { Dictionary <RmlEditorViewInfo, LayoutContainer> layoutPositions = new Dictionary <RmlEditorViewInfo, LayoutContainer>(); if (slideEditorController.ResourceProvider != null) { //Setup a LayoutChain to mimic the main one. LayoutChain layoutChain = new LayoutChain(); layoutChain.addLink(new PopupAreaChainLink(GUILocationNames.ContentAreaPopup), true); layoutChain.addLink(new BorderLayoutNoAnimationChainLink(GUILocationNames.ContentArea), true); IntSize2 thumbTotalSize = new IntSize2(SlideImageManager.ThumbWidth, SlideImageManager.ThumbHeight); FreeImageBitmap thumb = slideEditorController.SlideImageManager.createThumbBitmap(slide); layoutChain.SuppressLayout = true; LayoutContainer sceneContainer = new NullLayoutContainer(thumbTotalSize); layoutChain.addContainer(new BorderLayoutElementName(GUILocationNames.ContentArea, BorderLayoutLocations.Center), sceneContainer, null); foreach (var editor in rmlEditors.Values) { if (editor.Component != null) { float sizeRatio = (float)SlideImageManager.ThumbHeight / editor.Component.ViewHost.Container.RigidParentWorkingSize.Height; IntSize2 size = (IntSize2)(editor.Component.ViewHost.Container.DesiredSize * sizeRatio); NullLayoutContainer container = new NullLayoutContainer(size); layoutPositions.Add(editor, container); layoutChain.addContainer(editor.View.ElementName, container, null); } } layoutChain.SuppressLayout = false; layoutChain.WorkingSize = thumbTotalSize; layoutChain.Location = new IntVector2(0, 0); layoutChain.layout(); //Render thumbnail, Start with the scene IntVector2 sceneThumbPosition = sceneContainer.Location; String sceneThumbFile = slide.SceneThumbName; if (forceUpdateSceneThumb) { slideEditorController.SlideImageManager.addUnsavedSceneThumb(slide, renderSceneThumbnail()); } SceneThumbInfo sceneThumbInfo = slideEditorController.SlideImageManager.loadThumbSceneBitmap(slide, renderSceneThumbnail); IntSize2 centerSize = sceneContainer.WorkingSize; RectangleF destRect = new RectangleF(sceneThumbPosition.x, sceneThumbPosition.y, centerSize.Width, centerSize.Height); thumb.FillBackground(new RGBQUAD(FreeImageAPI.Color.FromArgb(sceneThumbInfo.Color.toARGB()))); int requiredWidth = (sceneThumbInfo.SceneThumb.Width - ((sceneThumbInfo.SceneThumb.Width - sceneThumbInfo.IncludeX) * 2)); int requiredHeight = (sceneThumbInfo.SceneThumb.Height - (sceneThumbInfo.IncludeY * 2)); int sceneThumbWidth = sceneThumbInfo.SceneThumb.Width; int sceneThumbHeight = sceneThumbInfo.SceneThumb.Height; int sceneThumbHalfWidth = sceneThumbWidth / 2; int sceneThumbHalfHeight = sceneThumbHeight / 2; float requiredHeightWidthRatio = (float)requiredHeight / requiredWidth; float centerHeightWidthRatio = (float)centerSize.Height / centerSize.Width; float srcWidth = requiredWidth; float srcHeight = requiredHeight; if (requiredHeightWidthRatio < centerHeightWidthRatio) //Compare ratios between our source required area and the destination { //Use the full required width, add height from source image //Convert the center size to the same size ratio as the required size float sizeRatio = (float)requiredWidth / centerSize.Width; srcHeight = centerSize.Height * sizeRatio; if (srcHeight > sceneThumbHeight) //Stretch out the image as much as possible, limiting by the size of the scene thumb if needed. { srcHeight = sceneThumbHeight; } float destHeight = srcHeight / sizeRatio; destRect = new RectangleF(destRect.Left, destRect.Height / 2 + destRect.Top - destHeight / 2, destRect.Width, destHeight); //Make a dest rect that takes as much image as it can } else { //Use the full required height, add width from source image float sizeRatio = (float)requiredHeight / centerSize.Height; srcWidth = centerSize.Width * sizeRatio; if (srcWidth > sceneThumbWidth) { srcWidth = sceneThumbWidth; } float destWidth = srcWidth / sizeRatio; destRect = new RectangleF(destRect.Width / 2 + destRect.Left - destWidth / 2, destRect.Top, destWidth, destRect.Height); } RectangleF srcRect = new RectangleF(sceneThumbHalfWidth - srcWidth / 2, sceneThumbHalfHeight - srcHeight / 2, srcWidth, srcHeight); using (FreeImageBitmap resizedSceneThumb = sceneThumbInfo.SceneThumb.Copy((int)srcRect.X, (int)srcRect.Y, (int)srcRect.Right, (int)srcRect.Bottom)) { resizedSceneThumb.Rescale((int)destRect.Width, (int)destRect.Height, FREE_IMAGE_FILTER.FILTER_BILINEAR); thumb.Paste(resizedSceneThumb, (int)destRect.X, (int)destRect.Y, int.MaxValue); } //Render all panels foreach (var editor in rmlEditors.Values) { if (editor.Component != null) { LayoutContainer container; if (layoutPositions.TryGetValue(editor, out container)) { Rectangle panelThumbPos = new Rectangle(container.Location.x, container.Location.y, container.WorkingSize.Width, container.WorkingSize.Height); editor.Component.writeToGraphics(thumb, panelThumbPos); } } } slideEditorController.SlideImageManager.thumbnailUpdated(slide); } }