【问题标题】:.net Drawing.Graphics.FromImage() returns blank black image.net Drawing.Graphics.FromImage() 返回空白黑色图像
【发布时间】:2011-02-26 19:49:24
【问题描述】:

我正在尝试在 asp.net 中重新缩放上传的 jpeg

所以我走了:

Image original = Image.FromStream(myPostedFile.InputStream);
int w=original.Width, h=original.Height;

using(Graphics g = Graphics.FromImage(original))
{
 g.ScaleTransform(0.5f, 0.5f); ... // e.g.
 using (Bitmap done = new Bitmap(w, h, g))
 {
  done.Save( Server.MapPath(saveas), ImageFormat.Jpeg );
  //saves blank black, though with correct width and height
 }
}

无论我给它什么文件,这都会保存一个原始的黑色 jpeg。 虽然如果我将输入图像流立即输入done 位图,它会重新压缩并保存它,例如:

Image original = Image.FromStream(myPostedFile.InputStream);
using (Bitmap done = new Bitmap(original))
{
 done.Save( Server.MapPath(saveas), ImageFormat.Jpeg );
}

我必须用 g 施展魔法吗?

更新: 我试过了:

Image original = Image.FromStream(fstream);
int w=original.Width, h=original.Height;
using(Bitmap b = new Bitmap(original)) //also tried new Bitmap(w,h)
 using (Graphics g = Graphics.FromImage(b))
 {
  g.DrawImage(original, 0, 0, w, h); //also tried g.DrawImage(b, 0, 0, w, h)
  using (Bitmap done = new Bitmap(w, h, g))
  {
   done.Save( Server.MapPath(saveas), ImageFormat.Jpeg );
  }
 }

同样的故事 - 正确尺寸的纯黑色

【问题讨论】:

    标签: asp.net graphics upload system.drawing rescale


    【解决方案1】:

    试试这个: - 从您的流中获取图像 - 创建正确大小的新位图 - 从新的位图中获取图形对象,而不是原来的 - 调用 g.DrawImage(original, 0, 0, done.Width, done.Height)

    编辑: 问题出在这部分:

    using (Bitmap done = new Bitmap(w, h, g)) 
      { 
       done.Save( Server.MapPath(saveas), ImageFormat.Jpeg ); 
      }
    

    您正在创建一个黑色位图,其分辨率由 g 指定。您实际上并没有使用来自 g 的任何图像数据创建位图。事实上,我不认为 Graphics 对象实际上存储了您可以真正传递的图像数据,它只是允许您操作一些存储图像数据的对象。

    尝试用 b.Save(...) 替换它

    【讨论】:

    • b.Save(...) 确实保存图像数据,但不应用转换。它可以通过使用b=new Bitmap(original,newWidth,newHeight) 轻松重新缩放,但我实际上需要对原始图像进行一系列转换,包括重新缩放、裁剪和旋转,因此尝试通过Graphics 进行,并将最终结果渲染为位图。我误解了Graphics 对象吗?
    • 正确的模式是 1) 获取 jpeg 文件 2) 依次对其应用多个转换 3) 保存它?听起来很简单……
    • 我认为更接近于说你误解了变换。大约 7 年前,我从大学开始就真的没有处理过变形,所以我有点生疏了。但我做了一个简单的旋转测试,它奏效了。诀窍是您不是在旋转图像数据,而是在旋转图形上下文,然后使用该旋转的上下文来绘制图像。所以在我的例子中,对 g.RotateTransform() 的调用需要在调用 g.DrawImage() 之前发生。这最终会如何影响你……很难说。但是变换的累积效果可能很有趣,而且操作顺序可能很重要。
    • 顺序问题 b/c 变换基本上是矩阵运算,矩阵乘法不是可交换的,就像标量乘法一样。我在 OpenGL 环境中使用变换,我经常发现自己对正确的操作顺序和使用的值感到惊讶——有时它与我预期的相反或相反。
    【解决方案2】:

    由于您没有用您正在从 inputStream 读取的图像背景填充区域,因此您只能通过这种方式获得空白图像。

    您可以使用将背景填充到调整大小的区域中,而不是使用缩放图像。

    看看这个:

    Image img = Image.FromFile(Server.MapPath("a.png"));
    int w = img.Width;
    int h = img.Height;
    
    //Create an empty bitmap with scaled size,here half
    Bitmap bmp = new Bitmap(w / 2, h / 2);
    //Create graphics object to draw
    Graphics g = Graphics.FromImage(bmp);
    //You can also use SmoothingMode,CompositingMode and CompositingQuality
    //of Graphics object to preserve saving options for new image.        
    
    //Create drawing area with a rectangle
    Rectangle drect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    //Draw image into your rectangle area
    g.DrawImage(img, drect);
    //Save your new image
    bmp.Save(Server.MapPath("a2.jpg"), ImageFormat.Jpeg);
    

    希望这会有所帮助
    迈拉

    【讨论】:

    • 谢谢,这是有道理的。我做了一点不同,但你的代码很好的说明
    • 你在哪里用图像背景填充区域
    • 在g.DrawImage(img, drect)的行中; ,这段代码确实填充了背景!
    猜你喜欢
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    相关资源
    最近更新 更多