Image.FromStream (PostedFile.InputStream) falha. (Parâmetro não é válido.) (AsyncFileUpload))
-
06-07-2019 - |
Pergunta
Eu estou usando um AsyncFileUpload (AJAX Toolkit) para fazer upload de imagens. Eu tenho um botão que lidar com o redimensionamento da imagem. Este tem trabalhado muito bem por algum tempo, mas não mais ...
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);
...
}
Outra coisa que eu acho estranho: Se eu tentar uma imagem que é menor do que 80kb ele funciona ..
!Temos tentado reiniciar o servidor, mas nenhuma mudança. Mesmo código funciona bem na minha máquina. (Ouvi isso antes ?? :))
Eu também tentou salvar o arquivo no servidor, em seguida, para obter o arquivo trough Image.FromFile (), mas depois eu recebo "Não é possível acessar um arquivo fechado".
Como resolver isso?
Solução
Gostaria de ter certeza do fluxo é posicionado no início:
var file = AsyncFileUpload1.FileContent;
file.Seek(0, SeekOrigin.Begin);
var img = Image.FromFile(file);
A segunda coisa a verificar: configuração do requestLengthDiskThreshold
. A menos que especificado essa configuração tem um padrão de ... sim, 80 KB.
Nota: imo não deve haver nenhuma diferença global se você usa imagem para ler o fluxo de arquivo diretamente ou se você usar um MemoryStream intermediário (além do fato de que, neste último caso você realmente carrega o arquivo inteiro na memória duas vezes). De qualquer maneira o fluxo de arquivo original será lido a partir, assim a posição de fluxo, CAS direitos, permissões de arquivos, etc ainda se aplica.
Nota 2: e, sim, por todos os meios garantir que esses recursos são descartados corretamente :)
Outras dicas
Esta é correto, ele não vai funcionar. O problema é que você está atravessando um limite gerenciado /, recentemente encontrou o mesmo. Outros problemas são que o fluxo não é diretamente lá eo Image.FromStream não tem idéia de como lidar com ele.
A solução é bastante simples: tudo leitura de PostedFile em um MemoryStream (new MemoryStream()
apenas uso) e usar o MemoryStream com o Image.FromStream
. Isto irá resolver o seu problema.
Certifique-se de fazer uso adequado de using
quando você trabalha com Image
, Graphics
e Stream
s. Todos eles implementar o IDisposable e em um ambiente ASP.NET, não usando blocos using
corretamente, pode e vai levar ao aumento do uso de memória e outro efeito colateral desagradável no longo prazo (e aplicativos ASP.NET são executados muito tempo!).
A solução deve ser algo como isto:
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:. a travessia conseguiu questão fronteira só ocorre no sentido inverso (usando fluxo de resposta), ao que parece, não com Carregar córregos, mas eu não sou inteiramente certo