Image.FromStream(PostedFile.InputStream) 失败。 (参数无效。)(AsyncFileUpload))

发布于 2024-08-09 07:10:00 字数 843 浏览 3 评论 0原文

我正在使用 AsyncFileUpload(AJAX 工具包)来上传图像。 我有一个处理图像大小调整的按钮。 这已经工作了一段时间,但现在不行了......

protected void BtnUploadImage_Click(object sender, EventArgs e)
{
    var imageFileNameRegEx = new Regex(@"(.*?)\.(jpg|jpeg|png|gif)$", 
        RegexOptions.IgnoreCase);
    if (!AsyncFileUpload1.HasFile || 
        !imageFileNameRegEx.IsMatch(AsyncFileUpload1.FileName))
    {
        AsyncFileUpload1.FailedValidation = true;
        ErrorLabel.Visible = true;
        return;
    }
    ErrorLabel.Visible = false;

    var file = AsyncFileUpload1.PostedFile.InputStream;

    var img = Image.FromStream(file, false, false);

...
}

另一件事我觉得很奇怪:如果我尝试小于 80kb 的图像,它就可以工作......!

我们尝试过重新启动服务器,但没有任何变化。 相同的代码在我的机器上运行良好。 (之前听说过??:))

我还尝试将文件保存在服务器上,然后通过 Image.FromFile() 获取文件,但后来我得到“无法访问已关闭的文件”。

如何解决这个问题?

I'm using an AsyncFileUpload (AJAX Toolkit) to upload images.
I have a Button which handle the image resizing.
This have worked fine for some time, but not anymore...

protected void BtnUploadImage_Click(object sender, EventArgs e)
{
    var imageFileNameRegEx = new Regex(@"(.*?)\.(jpg|jpeg|png|gif)$", 
        RegexOptions.IgnoreCase);
    if (!AsyncFileUpload1.HasFile || 
        !imageFileNameRegEx.IsMatch(AsyncFileUpload1.FileName))
    {
        AsyncFileUpload1.FailedValidation = true;
        ErrorLabel.Visible = true;
        return;
    }
    ErrorLabel.Visible = false;

    var file = AsyncFileUpload1.PostedFile.InputStream;

    var img = Image.FromStream(file, false, false);

...
}

Another thing which I find weird: If I try a image which is smaller than 80kb it works..!

We have tried to restart the server, but no change.
Same code runs fine on my machine. (heard that before ?? :) )

I also tried to save the file on the server, then to get the file trough Image.FromFile(), but then I get "Cannot access a closed file."

How to resolve this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

椵侞 2024-08-16 07:10:00

我会确保流位于开头:

var file = AsyncFileUpload1.FileContent;
file.Seek(0, SeekOrigin.Begin);

var img = Image.FromFile(file);

第二件事要检查: <代码>requestLengthDiskThreshold设置。除非指定,否则此设置的默认值为...是的,80 KB。

注意: 在我看来,无论您使用 Image 直接读取文件流还是使用中间 MemoryStream(除了在后一种情况下您实际上将整个文件加载到记忆两次)。无论哪种方式,都会读取原始文件流,因此流位置、CAS 权限、文件权限等仍然适用。

注2:是的,请务必确保这些资源得到正确处置:)

I would make sure the stream is positioned at the start:

var file = AsyncFileUpload1.FileContent;
file.Seek(0, SeekOrigin.Begin);

var img = Image.FromFile(file);

Second thing to check: the requestLengthDiskThreshold setting. Unless specified this setting has a default of ... yes, 80 KB.

Note: imo there should be no overall difference whether you use Image to read the file stream directly or if you use an intermediate MemoryStream (other than the fact that in the latter case you actually loads the entire file into memory twice). Either way the original file stream will be read from, thus stream position, CAS rights, file permissions, etc still applies.

Note2: and yes, by all means make sure those resources are disposed properly :)

白色秋天 2024-08-16 07:10:00

这是正确的,这是行不通的。问题是你正在跨越托管/非托管边界,我最近遇到了同样的问题。其他问题是流并不直接存在,并且 Image.FromStream 不知道如何处理它。

解决方案非常简单:将 PostedFile 中的所有内容读取到 MemoryStream 中(只需使用 new MemoryStream() )并将 MemoryStream 与 Image.FromStream 结合使用。这将解决您的问题。

当您使用 ImageGraphicsStream 时,请确保正确使用 using。它们都实现了 IDisposable,并且在 ASP.NET 环境中,如果不正确使用 using 块,从长远来看可能会导致内存使用量增加和其他令人讨厌的副作用(以及 ASP.NET 应用程序)确实跑很长时间!)。

解决方案应如下所示:

using(Stream memstr = new MemoryStream())
{
    // copy to a memory stream
    Stream uploadStream = AsyncFileUpload1.PostedFile.InputStream;
    byte[] all = new byte[uploadStream.Length];
    uploadStream.Read(all, 0, uploadStream.Length);
    memstr.Write(all, 0, uploadStream.Length);
    memstr.Seek(0, SeekOrigin.Begin);
    using(Graphics g = Graphics.FromStream(memstr))
    {
         // do your img manipulation, or Save it.
    }
}

更新: 跨越托管边界问题仅发生在相反的情况(使用响应流),似乎与上传流无关,但我不完全确定。

This is correct, it will not work. The problem is that you are crossing a managed/unmanaged boundary, I recently encountered the same. Other problems are that the stream is not directly there and the Image.FromStream has no idea how to deal with it.

The solution is quite straightforward: read everything from PostedFile into a MemoryStream (just use new MemoryStream()) and use the MemoryStream with the Image.FromStream. This will solve your problem.

Make sure to make proper use of using when you work with Image, Graphics and Streams. All of them implement the IDisposable and in an ASP.NET environment, not using using blocks properly, can and will lead to increased memory usage and other nasty side effect on the long run (and ASP.NET apps do run very long!).

The solution should look something like this:

using(Stream memstr = new MemoryStream())
{
    // copy to a memory stream
    Stream uploadStream = AsyncFileUpload1.PostedFile.InputStream;
    byte[] all = new byte[uploadStream.Length];
    uploadStream.Read(all, 0, uploadStream.Length);
    memstr.Write(all, 0, uploadStream.Length);
    memstr.Seek(0, SeekOrigin.Begin);
    using(Graphics g = Graphics.FromStream(memstr))
    {
         // do your img manipulation, or Save it.
    }
}

Update: the crossing managed boundary issue only occurs in the reverse (using Response stream), it seems, not with Upload streams, but I'm not entirely sure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文