我正在使用.NET应用程序来使用ImageMagick来减少图像文件的大小。我的应用程序在Hashtable
中存储了一些“设置”,以便在应用程序的各个区域中使用。我现在正在添加一个功能,以根据转换后的图像中所需的DPI来缩小图像大小。基本上,我在未改变的图像中查找DPI,计算所需DPI相对于当前DPI的百分比,然后我将按此比例调整图像尺寸。
ImageMagick将图像DPI报告为浮点值。所以200x200 DPI真的是199.975x199.975。因此,我使用Math.Ceiling()
将值输入到我的应用程序中。当我尝试使用我的设置Hashtable
中所需的DPI来进行百分比计算时,我得到了无效的强制转换异常。我不知道为什么会这样。
这是一个测试用例,其失败方式与我的实际代码相同:
using System;
using System.Collections;
namespace typetest
{
class Program
{
private struct DPI {
public double x;
public double y;
}
public static void Main(string[] args)
{
Hashtable vars = new Hashtable();
DPI dpi;
string dpiString = "199.547:199.547";
string[] ret;
vars["newDpiX"] = 150;
vars["newDpiY"] = 150;
ret = dpiString.Split(':');
dpi.x = ( (double)vars["newDpiX"] / Math.Ceiling(double.Parse(ret[0])) ) * 100;
dpi.y = ( (double)vars["newDpiY"] / Math.Ceiling(double.Parse(ret[1])) ) * 100;
Console.WriteLine("New DPI percentage = " + dpi.x + "%x" + dpi.y +"%");
}
}
}
如果我将分部改为
double newDpiX = 150.0;
dpi.x = ( newDpiX / Math.Ceiling(double.Parse(ret[0])) ) * 100;
它将按预期工作。这是怎么回事?
答案 0 :(得分:5)
Hashtable存储对象。当你在一个对象中放入一个int时,你会“装箱”它。拆箱需要相同的类型,不能直接从盒装int转换为double。
这将失败:
object obj = 10;
double dbl = (double)obj;
这将成功:
object obj = 10d; // a double value, could also have been 10.0
double dbl = (double)obj;
这也有效:
object obj = 10; // an int
double dbl = (double)(int)obj;
首先拆箱到一个int然后再转换为double。
编辑:
另见http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx
答案 1 :(得分:3)
尝试
vars["newDpiX"] = 150d;
答案 2 :(得分:1)
使用:
dpi.y = ( Convert.ToDouble(vars["newDpiY"]) / Math.Ceiling(double.Parse(ret[1])) ) * 100;
我认为你的问题是vars [“newDpiY”] = 150;存储一个int,而不是double。
答案 3 :(得分:0)
Hashtable hold对象,为其分配150,因此它存储为int。尝试指定150.0或(双)150或其他任何效果。