فهرست منبع

several upgrades to image viewer

lviguier 1 سال پیش
والد
کامیت
7e69e04487
3فایلهای تغییر یافته به همراه373 افزوده شده و 71 حذف شده
  1. 59 5
      bin/style.css
  2. 82 13
      bin/style.less
  3. 232 53
      hide/view/Image.hx

+ 59 - 5
bin/style.css

@@ -1143,28 +1143,82 @@ input[type=checkbox]:checked:after {
   margin: 4px;
   background-color: #1e1e1e;
 }
-.image-properties .save-compression,
-.image-properties .reset-preview {
-  width: 100%;
-  margin: 4px;
+.image-properties .preview-btns {
+  display: flex;
+  flex-direction: row;
+}
+.image-properties .preview-btns input[type="button"] {
+  flex: 1;
+  margin: 5px 5px 5px 5px;
+}
+.image-properties .reset-compression {
+  outline: 2px solid #fd5151;
+  width: 95%;
+  margin-left: 2.5%;
 }
 .image-properties .compression-infos {
   width: 100%;
   margin-top: 10px;
   margin-bottom: 10px;
 }
+.image-properties .compression-infos p {
+  margin: 0px 0px 0px 5px;
+  font-weight: bold;
+  text-align: center;
+}
 .image-properties .field {
-  margin: 5px 5px 0 50px;
+  margin: 5px 5px 0px 50px;
   display: flex;
   flex-direction: row;
 }
+.image-properties .field.alpha {
+  margin: 5px 5px 5px 80px;
+}
+.image-properties .field.alpha label {
+  flex: 1;
+  flex-shrink: 0;
+  white-space: nowrap;
+}
+.image-properties .field.alpha input[type="checkbox"] {
+  margin-right: 5px;
+}
+.image-properties .field.alpha input[type="number"] {
+  flex: 1;
+}
+.image-properties .field.alpha input[type="number"]:disabled {
+  pointer-events: none;
+  background-color: #111111;
+  color: #757575;
+}
 .image-properties .field label {
   margin-right: 4px;
 }
+.image-properties .field .size {
+  width: 50px;
+  margin-right: 5px;
+}
 .image-properties .field select,
 .image-properties .field input[type="text"] {
   flex-grow: 1;
 }
+.identifiers {
+  position: absolute;
+  left: 0;
+  right: 320px;
+  bottom: 50px;
+}
+.identifiers label {
+  position: absolute;
+  color: white;
+  font-weight: bold;
+  font-size: 30px;
+}
+.identifiers :nth-child(1) {
+  left: 20px;
+}
+.identifiers :nth-child(2) {
+  right: 20px;
+}
 /* Curve editor */
 .hide-curve-editor {
   position: relative;

+ 82 - 13
bin/style.less

@@ -1222,10 +1222,11 @@ input[type=checkbox] {
 	}
 }
 /* Image Viewer */
+@imgPanelWidht : 320px;
 .image-properties {
 	height : 100%;
 	background-color: #111;
-	width: 320px;
+	width: @imgPanelWidht;
 
 	.title {
 		text-align: center;
@@ -1234,32 +1235,100 @@ input[type=checkbox] {
 		background-color : rgb(30,30,30);
 	}
 
-	.save-compression, .reset-preview {
-		width: 100%;
-		margin: 4px;
+	.preview-btns {
+		display:flex;
+		flex-direction: row;
+
+		input[type="button"] {
+			flex: 1;
+			margin: 5px 5px 5px 5px;
+		}
+	}
+
+	.reset-compression {
+		outline: 2px solid #fd5151;
+		width: 95%;
+		margin-left: 2.5%;
 	}
 
 	.compression-infos {
 		width: 100%;
 		margin-top: 10px;
 		margin-bottom: 10px;
+
+		p {
+			margin: 0px 0px 0px 5px;
+			font-weight: bold;
+			text-align: center;
+		}
 	}
 
 	.field {
-		margin: 5px 5px 0 50px;
+		margin: 5px 5px 0px 50px;
 		display: flex;
     	flex-direction: row;
 
+		&.alpha {
+			margin: 5px 5px 5px 80px;
+
+			label {
+				flex: 1;
+				flex-shrink: 0;
+				white-space: nowrap;
+			}
+
+			input[type="checkbox"]{
+				margin-right: 5px;
+			}
+
+			input[type="number"]{
+				flex: 1;
+
+				&:disabled {
+					pointer-events: none;
+					background-color: #111111;
+					color: #757575;
+				}
+			}
+		}
+
 		label {
 			margin-right: 4px;
 		}
 
+		.size {
+			width: 50px;
+			margin-right: 5px;
+		}
+
 		select, input[type="text"] {
 			flex-grow: 1;
 		}
 	}
 }
 
+.identifiers {
+	position: absolute;
+	left: 0;
+	right: @imgPanelWidht;
+	bottom: 50px;
+
+	label {
+		position: absolute;
+		color: white;
+		font-weight: bold;
+		font-size: 30px;
+	}
+
+	:nth-child(1) {
+		left: 20px;
+	}
+
+	:nth-child(2) {
+		right:20px;
+	}
+}
+
 
 /* Curve editor */
 @timelineHeight: 20px;
@@ -1511,7 +1580,7 @@ input[type=checkbox] {
 	.key-event.selected, .key-event:hover.selected {
 		fill: #ffbe33;
 	}
-	
+
 	text {
 		font: 10px sans-serif; fill: #8d8d8d;
 	}
@@ -1592,7 +1661,7 @@ input[type=checkbox] {
 		background: #4a4a4a;
 		text-align: left;
 		white-space: nowrap;
-		
+
 		.name {
 			padding: 1px;
 			padding-left: 5px;
@@ -1636,17 +1705,17 @@ input[type=checkbox] {
 		position: relative;
 		background: #1b1b1b;
 		text-align: left;
-		
+
 		&.hidden {
 			display: none;
 		}
-		
+
 		.name {
 			padding: 1px;
 			padding-left: 5px;
 			padding-right: 5px;
 		}
-		
+
 		.abspath {
 			position: absolute;
 			opacity: 0.5;
@@ -1695,7 +1764,7 @@ input[type=checkbox] {
 		}
 	}
 
-	.track {		
+	.track {
 		min-height: 20px;
 		display: flex;
 		user-select: none;
@@ -1721,11 +1790,11 @@ input[type=checkbox] {
 				background: rgba(0, 0, 0, 0.438);
 			}
 		}
-			
+
 		&.hidden {
 			display: none;
 		}
-		
+
 		.curve {
 			margin-left: @leftPanelWidth;
 			position: relative;

+ 232 - 53
hide/view/Image.hx

@@ -80,23 +80,33 @@ class Image extends FileView {
 			<div class="flex vertical">
 				<div class="toolbar"></div>
 				<div class="scene-partition" style="display: flex; flex-direction: row; flex: 1; overflow: hidden;">
-					<div class="heaps-scene"></div>
-					<div class="image-properties">
-						<div class="title">Image compression</div>
-						<div class="compression-infos"></div>
-						<input type="button" class="reset-preview" value="Reset preview"/>
-						<input type="button" class="save-compression" value="Save"/>
+				<div class="heaps-scene"></div>
+				<div class="image-properties">
+					<div class="title">Image compression</div>
+					<div class="compression-infos">
+						<p class="comp-tex-weight">Compressed texture weight : missing info </p>
+						<p class="uncomp-tex-weight">Uncompressed texture weight : missing info</p>
 					</div>
+						<div class="preview-btns">
+							<input type="button" class="reset-preview" value="Reset preview" title="Reset preview compression."/>
+							<input type="button" class="save-compression" value="Save" title="Save current compression options into a props.json file."/>
+						</div>
+						<input type="button" class="reset-compression" value="Reset compression" title="Remove the current compression\'s rules applied to this texture, from props.json file."/>
+					</div>
+				</div>
+				<div class="identifiers">
+					<label>Compressed texture</label>
+					<label>Uncompressed texture</label>
 				</div>
 			</div>
 		');
 
 		scene = new hide.comp.Scene(config, null, element.find(".heaps-scene"));
 
-		function addField(parent: Element, label:String, selectClass:String, options:Array<String>) {
+		function addField(parent: Element, label:String, title:String, selectClass:String, options:Array<String>) {
 			var field = new Element('<div class="field">
 				<label>${label}</label>
-				<select class="${selectClass}">
+				<select class="${selectClass}" title="${title}">
 				</select>
 			</div>');
 
@@ -109,39 +119,36 @@ class Image extends FileView {
 		}
 
 		var compressionInfo = element.find(".compression-infos");
-		addField(compressionInfo, "Format :", "select-format", ["none", "BC1", "BC2", "BC3", "RGBA", "R16F", "RG16F", "RGBA16F", "R32F", "RG32F", "RGBA32F", "R16U", "RG16U", "RGBA16U"] );
+		addField(compressionInfo, "Format :", "Compression format used to compress texture", "select-format", ["none", "BC1", "BC2", "BC3", "RGBA", "R16F", "RG16F", "RGBA16F", "R32F", "RG32F", "RGBA32F", "R16U", "RG16U", "RGBA16U"] );
+
+		var alphaField = new Element('<div class="field alpha">
+			<label>Alpha :</label>
+			<input type="checkbox" class="use-alpha" title="Does the BC1 format use alpha"></input>
+			<input type="number" class="alpha-threshold" placeholder="Alpha threshold" title="Alpha threshold value"></input>
+		</div>');
+		compressionInfo.append(alphaField);
 
 		var mipsField = new Element('<div class="field">
-			<label>Mip maps :</label>
-			<input type="checkbox" class="mips-checkbox"></input>
+		<label>Mip maps :</label>
+		<input type="checkbox" class="mips-checkbox" title="Generate mip maps for the texture"></input>
 		</div>');
 		compressionInfo.append(mipsField);
 
 		var sizeField = new Element('<div class="field">
-			<label>Size :</label>
-			<input type="text" class="size"></input>
+		<label>Size :</label>
+		<input type="number" class="size"></input>
+		<label class="max-size">/ 128 px</label>
 		</div>');
 		compressionInfo.append(sizeField);
 
-		var alphaField = new Element('<div class="field">
-			<label>Alpha :</label>
-			<input type="text" class="alpha-threshold"></input>
-		</div>');
-		compressionInfo.append(alphaField);
-
 		var format = compressionInfo.find(".select-format");
 		var mips = compressionInfo.find(".mips-checkbox");
 		var size = compressionInfo.find(".size");
+		var useAlpha = compressionInfo.find(".use-alpha");
 		var alpha = compressionInfo.find(".alpha-threshold");
 
-		var fs:hxd.fs.LocalFileSystem = Std.downcast(hxd.res.Loader.currentInstance.fs, hxd.fs.LocalFileSystem);
-		@:privateAccess var textureConvertRule = fs.convert.getConvertRule(state.path);
-
-		var convertRuleEmpty = textureConvertRule == null || textureConvertRule.cmd == null || textureConvertRule.cmd.params == null;
-
-		format.val(convertRuleEmpty ? "none" : textureConvertRule.cmd.params.format);
 		format.on("change", function(_) {
-			createPreviewTexture(format, alpha, mips, size);
+			createPreviewTexture(format, useAlpha, alpha, mips, size);
 
 			// Alpha treshold make sense for BC1 format
 			if (format.val() != "BC1")
@@ -150,44 +157,67 @@ class Image extends FileView {
 				alpha.parent().css({"display":"flex"});
 		});
 
-		alpha.val(convertRuleEmpty || Reflect.field(textureConvertRule.cmd.params, "alpha") == null ? "undefined" : textureConvertRule.cmd.params.alpha);
-		alpha.on("change", function(_) {
-			createPreviewTexture(format, alpha, mips, size);
+		useAlpha.on("change", function(_) {
+			if (useAlpha.is(':checked')) {
+				alpha.removeAttr("disabled");
+
+				if (alpha.val() == null || alpha.val() == "")
+					alpha.val(128);
+			}
+			else {
+				alpha.prop("disabled", true);
+			}
+
+			createPreviewTexture(format, useAlpha, alpha, mips, size);
 		});
 
-		// Alpha treshold make sense for BC1 format
-		if (format.val() != "BC1")
-			alpha.parent().css({"display":"none"});
-		else
-			alpha.parent().css({"display":"flex"});
+		alpha.on("change", function(_) {
+			createPreviewTexture(format, useAlpha, alpha, mips, size);
+		});
 
-		size.val(convertRuleEmpty || Reflect.field(textureConvertRule.cmd.params, "size") == null ? "undefined" : textureConvertRule.cmd.params.size);
 		size.on("change", function(_) {
-			createPreviewTexture(format, alpha, mips, size);
+			createPreviewTexture(format, useAlpha, alpha, mips, size);
 		});
 
-		if (!convertRuleEmpty && textureConvertRule.cmd.params.mips)
-			mips.prop("checked", true);
-		else
-			mips.removeProp("checked");
-
 		mips.on("change", function(_) {
-			createPreviewTexture(format, alpha, mips, size);
+			createPreviewTexture(format, useAlpha, alpha, mips, size);
 		});
 
+		var fs:hxd.fs.LocalFileSystem = Std.downcast(hxd.res.Loader.currentInstance.fs, hxd.fs.LocalFileSystem);
+		@:privateAccess var textureConvertRule = fs.convert.getConvertRule(state.path);
+
+		var convertRuleEmpty = textureConvertRule == null || textureConvertRule.cmd == null || textureConvertRule.cmd.params == null;
+
 		this.saveDisplayKey = state.path;
 		this.viewMode = getDisplayState("ViewMode");
 		if (this.viewMode == null)
 			this.viewMode = Compressed;
 
+		var identifiers = element.find(".identifiers");
+		identifiers.css(this.viewMode.match(ViewMode.Comparison) ? {"visibility":"inherit"} : {"visibility":"hidden"});
+
 		var dirPos = state.path.lastIndexOf("/");
 		var dirPath = dirPos < 0 ? state.path : state.path.substr(0, dirPos + 1);
+		var name = dirPos < 0 ? state.path : state.path.substr(dirPos + 1);
+		var propsFilePath = ide.getPath(dirPath + "props.json");
 
 		var resetPreview = element.find(".reset-preview");
 		resetPreview.on("click", function(_) {
+			var texMaxSize = getTextureMaxSize();
 			format.val(convertRuleEmpty ? "none" : textureConvertRule.cmd.params.format);
-			alpha.val(convertRuleEmpty || Reflect.field(textureConvertRule.cmd.params, "alpha") == null ? "undefined" : textureConvertRule.cmd.params.alpha);
-			size.val(convertRuleEmpty || Reflect.field(textureConvertRule.cmd.params, "size") == null ? "undefined" : textureConvertRule.cmd.params.size);
+			alpha.val(convertRuleEmpty || Reflect.field(textureConvertRule.cmd.params, "alpha") == null ? null : textureConvertRule.cmd.params.alpha);
+			size.val(convertRuleEmpty || Reflect.field(textureConvertRule.cmd.params, "size") == null ? texMaxSize : textureConvertRule.cmd.params.size);
+
+			if (Reflect.field(textureConvertRule.cmd.params, "alpha") != null) {
+				useAlpha.prop("checked", true);
+				alpha.removeAttr("disabled");
+				alpha.val(128);
+			}
+			else {
+				useAlpha.prop("checked", false);
+				alpha.prop("disabled", true);
+				alpha.val(null);
+			}
 
 			if (convertRuleEmpty && textureConvertRule.cmd.params.mips)
 				mips.prop("checked", true);
@@ -200,11 +230,12 @@ class Image extends FileView {
 			else
 				alpha.parent().css({"display":"flex"});
 
-			createPreviewTexture(format, alpha, mips, size);
+			createPreviewTexture(format, useAlpha, alpha, mips, size);
 		});
 
 		var saveCompression = element.find(".save-compression");
 		saveCompression.on("click", function(_) {
+			var texMaxSize = getTextureMaxSize();
 			var bytes = new haxe.io.BytesOutput();
 			var convertRule = { };
 
@@ -214,14 +245,13 @@ class Image extends FileView {
 			else {
 				convertRule = { convert : "dds", format : format.val(), mips : mips.is(':checked') };
 
-				if (size.val() != "undefined")
+				if (size.val() != texMaxSize)
 					Reflect.setField(convertRule, "size", size.val());
 
-				if (alpha.val() != "undefined")
+				if (useAlpha.is(':checked'))
 					Reflect.setField(convertRule, "alpha", alpha.val());
 			}
 
-			var propsFilePath = ide.getPath(dirPath + "props.json");
 			if (sys.FileSystem.exists(propsFilePath)) {
 				var propsJson = haxe.Json.parse(sys.io.File.getContent(propsFilePath));
 
@@ -229,6 +259,11 @@ class Image extends FileView {
 					var fsConvertObj = Reflect.getProperty(propsJson, "fs.convert");
 					Reflect.setField(fsConvertObj, state.path, convertRule);
 				}
+				else {
+					var fsConvertObj = {} ;
+					Reflect.setField(fsConvertObj, state.path, convertRule);
+					Reflect.setProperty(propsJson, "fs.convert", fsConvertObj);
+				}
 
 				var data = haxe.Json.stringify(propsJson, "\t");
 				bytes.writeString(data);
@@ -244,9 +279,6 @@ class Image extends FileView {
 				hxd.File.saveBytes(propsFilePath, bytes.getBytes());
 			}
 
-			var dirPos = state.path.lastIndexOf("/");
-			var name = dirPos < 0 ? state.path : state.path.substr(dirPos + 1);
-
 			@:privateAccess fs.convert.configs.clear();
 			@:privateAccess fs.convert.loadConfig(state.path);
 
@@ -254,6 +286,42 @@ class Image extends FileView {
 			fs.convert.run(localEntry);
 		});
 
+		var resetCompression = element.find(".reset-compression");
+		resetCompression.on("click", function(_) {
+			if (!sys.FileSystem.exists(propsFilePath))
+				ide.message('The file ${propsFilePath} does not exist !');
+
+			var rulesObj = haxe.Json.parse(sys.io.File.getContent(propsFilePath));
+
+			var fsConvertObj = Reflect.getProperty(rulesObj, "fs.convert");
+			if (fsConvertObj == null || Reflect.getProperty(fsConvertObj, state.path) == null)
+				ide.message('The file ${propsFilePath} does not contain compression rule for ${state.path} !');
+			else {
+				if(!ide.confirm('Do you really want to remove ${state.path} from ${propsFilePath} ?'))
+					return;
+
+				Reflect.deleteField(fsConvertObj, state.path);
+
+				if (Reflect.getProperty(rulesObj, fsConvertObj) == null)
+					Reflect.deleteField(rulesObj, "fs.convert");
+
+				if (Reflect.fields(rulesObj).length == 0) {
+					sys.FileSystem.deleteFile(propsFilePath);
+					updateImageCompressionInfos();
+					replaceImage(ide.getPath(state.path));
+					return;
+				}
+			}
+
+			var bytes = new haxe.io.BytesOutput();
+			var data = haxe.Json.stringify(rulesObj, "\t");
+			bytes.writeString(data);
+			hxd.File.saveBytes(propsFilePath, bytes.getBytes());
+
+			updateImageCompressionInfos();
+			replaceImage(ide.getPath(state.path));
+		});
+
 		shader = new ImageViewerShader();
 		tools = new hide.comp.Toolbar(null,element.find(".toolbar"));
 
@@ -267,6 +335,9 @@ class Image extends FileView {
 				this.saveDisplayState("ViewMode", Compressed);
 				this.viewMode = Compressed;
 
+				var identifiers = element.find(".identifiers");
+				identifiers.css(this.viewMode.match(ViewMode.Comparison) ? {"visibility":"inherit"} : {"visibility":"hidden"});
+
 				applyShaderConfiguration();
 			}
 		}, this.viewMode.match(Compressed));
@@ -280,6 +351,9 @@ class Image extends FileView {
 				this.saveDisplayState("ViewMode", Uncompressed);
 				this.viewMode = Uncompressed;
 
+				var identifiers = element.find(".identifiers");
+				identifiers.css(this.viewMode.match(ViewMode.Comparison) ? {"visibility":"inherit"} : {"visibility":"hidden"});
+
 				applyShaderConfiguration();
 			}
 
@@ -294,6 +368,9 @@ class Image extends FileView {
 				this.saveDisplayState("ViewMode", Comparison);
 				this.viewMode = Comparison;
 
+				var identifiers = element.find(".identifiers");
+				identifiers.css(this.viewMode.match(ViewMode.Comparison) ? {"visibility":"inherit"} : {"visibility":"hidden"});
+
 				applyShaderConfiguration();
 			}
 
@@ -384,6 +461,10 @@ class Image extends FileView {
 			tools.addRange("Exposure", function(f) shader.exposure = f, 0, -10, 10);
 		}
 
+		var compTexMemSize = element.find(".comp-tex-weight");
+		compTexMemSize.text('Compressed texture weight : ${@:privateAccess floatToStringPrecision(compressedTexture.mem.memSize(compressedTexture) / (1024 * 1024)) } mb');
+
+		updateImageCompressionInfos();
 		applyShaderConfiguration();
 		onResize();
 	}
@@ -479,6 +560,72 @@ class Image extends FileView {
 		shader = null;
 	}
 
+	public function updateImageCompressionInfos() {
+		var compressionInfo = element.find(".compression-infos");
+
+		// Compression infos fields
+		var format = compressionInfo.find(".select-format");
+		var mips = compressionInfo.find(".mips-checkbox");
+		var size = compressionInfo.find(".size");
+		var useAlpha = compressionInfo.find(".use-alpha");
+		var alpha = compressionInfo.find(".alpha-threshold");
+		var maxSize = compressionInfo.find(".max-size");
+
+		var dirPos = state.path.lastIndexOf("/");
+		var name = dirPos < 0 ? state.path : state.path.substr(dirPos + 1);
+
+		// We want to clear file system because we don't want to load texture from older texture's convert rules
+		var fs:hxd.fs.LocalFileSystem = Std.downcast(hxd.res.Loader.currentInstance.fs, hxd.fs.LocalFileSystem);
+		@:privateAccess fs.convert.configs.clear();
+		@:privateAccess fs.convert.loadConfig(state.path);
+
+		var localEntry = @:privateAccess new hxd.fs.LocalFileSystem.LocalEntry(fs, name, state.path, Ide.inst.getPath(state.path));
+		fs.convert.run(localEntry);
+
+		@:privateAccess var texConvRule = fs.convert.getConvertRule(state.path);
+		var convertRuleEmpty = texConvRule == null || texConvRule.cmd == null || texConvRule.cmd.params == null;
+
+		format.val(convertRuleEmpty ? "none" : texConvRule.cmd.params.format);
+
+		if (!convertRuleEmpty) {
+			if (Reflect.field(texConvRule.cmd.params, "alpha") != null) {
+				useAlpha.prop("checked", true);
+				alpha.removeAttr("disabled");
+				alpha.val(128);
+			}
+			else {
+				useAlpha.removeProp("checked");
+				alpha.prop("disabled", true);
+				alpha.val(null);
+			}
+		}
+
+		alpha.val(convertRuleEmpty || Reflect.field(texConvRule.cmd.params, "alpha") == null ? null : texConvRule.cmd.params.alpha);
+
+		// Alpha treshold make sense for BC1 format
+		if (format.val() != "BC1")
+			alpha.parent().css({"display":"none"});
+		else
+			alpha.parent().css({"display":"flex"});
+
+		var strMaxSize = getTextureMaxSize();
+		size.val(convertRuleEmpty || Reflect.field(texConvRule.cmd.params, "size") == null ? strMaxSize : texConvRule.cmd.params.size);
+
+		if (!convertRuleEmpty && texConvRule.cmd.params.mips)
+			mips.prop("checked", true);
+		else
+			mips.removeProp("checked");
+
+		var texMaxSize = getTextureMaxSize();
+
+		maxSize.text('/${texMaxSize} px');
+		if(size.val() == null || size.val() == "")
+			size.val(texMaxSize);
+
+		var uncompTWeight = element.find(".uncomp-tex-weight");
+		uncompTWeight.text('Uncompressed texture weight : ${getTextureMemSize(state.path)} mb');
+	}
+
 	public function replaceImage(path : String) {
 		var bytes = sys.io.File.getBytes(path);
 		var res = hxd.res.Any.fromBytes(path, bytes);
@@ -530,11 +677,14 @@ class Image extends FileView {
 			tools.addRange("Exposure", function(f) shader.exposure = f, 0, -10, 10);
 		}
 
+		var compTexMemSize = element.find(".comp-tex-weight");
+		compTexMemSize.text('Compressed texture weight : ${@:privateAccess floatToStringPrecision(t.mem.memSize(t) / (1024 * 1024)) } mb');
+
 		applyShaderConfiguration();
 		onResize();
 	}
 
-	public function createPreviewTexture(format: Element, alpha: Element, mips: Element, size: Element) {
+	public function createPreviewTexture(format: Element, useAlpha: Element, alpha: Element, mips: Element, size: Element) {
 		var dirPos = state.path.lastIndexOf("/");
 		var name = dirPos < 0 ? state.path : state.path.substr(dirPos + 1);
 		var tmpPath = StringTools.replace(Sys.getEnv("TEMP"), "\\","/") + "/tempTexture.dds";
@@ -544,7 +694,12 @@ class Image extends FileView {
 			comp.srcPath = Ide.inst.getPath(state.path);
 			comp.dstPath = Ide.inst.getPath(tmpPath);
 			comp.originalFilename = name;
-			comp.params = { alpha:Std.parseInt(alpha.val()), format:format.val().toString(), mips:mips.is(':checked'), size:Std.parseInt(size.val()) };
+
+			if (useAlpha.is(':checked'))
+				comp.params = { format:format.val().toString(), mips:mips.is(':checked'), size:Std.parseInt(size.val()) };
+			else
+				comp.params = { alpha:Std.parseInt(alpha.val()), format:format.val().toString(), mips:mips.is(':checked'), size:Std.parseInt(size.val()) };
+
 			comp.convert();
 		}
 		else {
@@ -554,6 +709,30 @@ class Image extends FileView {
 		replaceImage(Ide.inst.getPath(tmpPath));
 	}
 
+	public function getTextureMaxSize(): Int {
+		var path = ide.getPath(state.path);
+		var bytes = sys.io.File.getBytes(path);
+		var res = hxd.res.Any.fromBytes(path, bytes);
+		var t = res.toTexture();
+
+		return t.width;
+	}
+
+	public function getTextureMemSize(path: String) {
+		// Return texture mem size in MB
+		var p = ide.getPath(path);
+		var bytes = sys.io.File.getBytes(p);
+		var res = hxd.res.Any.fromBytes(p, bytes);
+		var t = res.toTexture();
+
+		return @:privateAccess floatToStringPrecision(t.mem.memSize(t) / (1024 * 1024));
+	}
+
+	public function floatToStringPrecision(number:Float, ?precision=2) {
+		number *= Math.pow(10, precision);
+		return Math.round(number) / Math.pow(10, precision);
+	}
+
 	static var _ = FileTree.registerExtension(Image,hide.Ide.IMG_EXTS.concat(["envd","envs"]),{ icon : "picture-o" });
 
 }