Parece ser um erro infame em toda a web. Tanto que não consegui encontrar uma resposta para o meu problema, pois meu cenário não se encaixa. Uma exceção é lançada quando eu salvo a imagem no fluxo.
Estranhamente, isso funciona perfeitamente com um png, mas gera o erro acima com jpg e gif, o que é bastante confuso.
O problema mais parecido está relacionado ao salvamento de imagens em arquivos sem permissão. Ironicamente, a solução é usar um fluxo de memória como eu estou fazendo ....
public static byte[] ConvertImageToByteArray(Image imageToConvert)
{
using (var ms = new MemoryStream())
{
ImageFormat format;
switch (imageToConvert.MimeType())
{
case "image/png":
format = ImageFormat.Png;
break;
case "image/gif":
format = ImageFormat.Gif;
break;
default:
format = ImageFormat.Jpeg;
break;
}
imageToConvert.Save(ms, format);
return ms.ToArray();
}
}
Mais detalhes à exceção. A razão pela qual isso causa tantos problemas é a falta de explicação :(
System.Runtime.InteropServices.ExternalException was unhandled by user code
Message="A generic error occurred in GDI+."
Source="System.Drawing"
ErrorCode=-2147467259
StackTrace:
at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(Stream stream, ImageFormat format)
at Caldoo.Infrastructure.PhotoEditor.ConvertImageToByteArray(Image imageToConvert) in C:\Users\Ian\SVN\Caldoo\Caldoo.Coordinator\PhotoEditor.cs:line 139
at Caldoo.Web.Controllers.PictureController.Croppable() in C:\Users\Ian\SVN\Caldoo\Caldoo.Web\Controllers\PictureController.cs:line 132
at lambda_method(ExecutionScope , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
InnerException:
OK coisas que eu tentei até agora.
- Clonando a imagem e trabalhando nisso.
- Recuperando o codificador para esse MIME passando isso com a configuração de qualidade jpeg.
Respostas:
OK, parece que encontrei a causa apenas por pura sorte e não há nada de errado com esse método específico, é ainda mais o backup da pilha de chamadas.
Anteriormente, redimensiono a imagem e, como parte desse método, retorno o objeto redimensionado da seguinte maneira. Eu inseri duas chamadas para o método acima e uma gravação direta em um arquivo.
Parece que o fluxo de memória em que o objeto foi criado precisa ser aberto no momento em que o objeto é salvo. Não sei por que isso acontece. Alguém é capaz de me esclarecer e como posso contornar isso.
Eu só retorno de um fluxo porque, depois de usar o código de redimensionamento semelhante a esse, o arquivo de destino tem um tipo mime desconhecido (img.RawFormat.Guid) e o ID do tipo Mime está correto em todos os objetos de imagem, o que dificulta a escrita genérica código de manipulação caso contrário.
EDITAR
Isso não apareceu na minha pesquisa inicial, mas aqui está a resposta de Jon Skeet
fonte
Se você está recebendo esse erro, posso dizer que seu aplicativo não tem permissão de gravação em algum diretório.
Por exemplo, se você estiver tentando salvar a imagem do fluxo de memória no sistema de arquivos, poderá receber esse erro.
Por favor, se você estiver usando o XP, adicione permissão de gravação para a conta aspnet nessa pasta.
Se você estiver usando o Windows server (2003,2008) ou o Vista, certifique-se de adicionar permissão de gravação à conta do serviço de rede.
Espero que ajude alguém.
fonte
Acrescentarei também a causa do erro, na esperança de ajudar algum futuro viajante da Internet. :)
GDI + limita a altura máxima de uma imagem a 65500
Fazemos um redimensionamento básico da imagem, mas, ao redimensionar, tentamos manter a proporção. Temos um cara de controle de qualidade que é um pouco bom demais nesse trabalho; ele decidiu testar isso com uma foto com UM pixel de largura e 480 pixels de altura. Quando a imagem foi dimensionada para atender às nossas dimensões, a altura estava ao norte de 68.000 pixels e nosso aplicativo explodiu com
A generic error occurred in GDI+
.Você pode verificar isso sozinho com o teste:
É uma pena que não haja um .net amigável
ArgumentException
lançado no construtor deBitmap
.fonte
Este artigo explica em detalhes o que exatamente acontece: Dependências do construtor Bitmap e Image
Em suma, por toda a vida de um
Image
construído a partir de um fluxo , o fluxo não deve ser destruído.Então, ao invés de
tente isso
e feche o imageStream no fechamento do formulário ou na página da web.
fonte
using
tentativa de, posteriormente, copiar a imagem em um fluxo de memória e recebi a terrível mensagem "Erro genérico no GDI +".PixelFormat.Format32bppArgb
mas não estavaPixelFormat.Format1bppIndexed
. O artigo vinculado explica o motivo: o GDI + pode optar por decodificar novamente os dados de bitmap do fluxo de origem, em vez de manter tudo na memória. Meu palpite é que ele não decodifica as imagens 1bpp.Você também receberá essa exceção se tentar salvar em um caminho inválido ou se houver um problema de permissão.
Se você não tem 100% de certeza de que o caminho do arquivo está disponível e as permissões estão corretas, tente gravar um em um arquivo de texto. Demora apenas alguns segundos para descartar o que seria uma correção muito simples.
E não se esqueça de limpar seu arquivo.
fonte
Salvar imagem na variável de bitmap
fonte
Caso alguém esteja fazendo coisas tão estúpidas quanto eu. 1. verifique se o caminho existe. 2. verifique se você tem permissões para escrever. 3. verifique se o caminho está correto, no meu caso estava faltando o nome do arquivo no TargetPath :(
deveria ter dito, seu caminho é péssimo do que "Ocorreu um erro genérico no GDI +"
fonte
Também recebi esse erro ao salvar JPEGs, mas apenas para determinadas imagens.
Meu código final:
Eu não criei as imagens, então não sei dizer qual é a diferença.
Eu apreciaria se alguém pudesse explicar isso.
Esta é a minha função SaveJpeg apenas FYI:
fonte
Descobri que, se uma das pastas pai em que eu estava salvando o arquivo tivesse um espaço à direita, o GDI + lançaria a exceção genérica.
Em outras palavras, se eu tentasse salvar em "C: \ Documents and Settings \ nome do usuário \ Configurações locais \ Temp \ ABC DEF M1 Valores de tendência \ Images \ picture.png", lançaria a exceção genérica.
O nome da minha pasta estava sendo gerado a partir de um nome de arquivo que tinha um espaço à direita, por isso foi fácil .Trim () e seguir em frente.
fonte
se o seu código for o seguinte, também ocorrerá este erro
O correto é
Isso pode ser porque estamos retornando do bloco using
fonte
Esta é uma expansão / qualificação da resposta de Fred, que declarou: "A GDI limita a altura de uma imagem a 65534". Deparamos com esse problema com um de nossos aplicativos .NET e, depois de ver o post, nossa equipe de terceirização levantou as mãos e disse que não poderia resolver o problema sem grandes alterações.
Com base nos meus testes, é possível criar / manipular imagens com uma altura maior que 65534, mas o problema surge ao salvar em um fluxo ou arquivo EM CERTOS FORMATOS . No código a seguir, a chamada do método t.Save () lança nosso amigo a exceção genérica quando a altura do pixel é 65501 para mim. Por motivos de curiosidade, repeti o teste de largura e o mesmo limite foi aplicado à economia.
O mesmo erro também ocorre se você gravar em um fluxo de memória.
Para contornar isso, você pode repetir o código acima e substituir ImageFormat.Tiff ou ImageFormat.Bmp por ImageFormat.Jpeg.
Isso atinge alturas / larguras de 100.000 para mim - eu não testei os limites. Por acaso .Tiff era uma opção viável para nós.
ESTEJA AVISADO
Os fluxos / arquivos TIFF na memória consomem mais memória do que seus equivalentes JPG.
fonte
Teve um problema muito semelhante e também tentou clonar a imagem que não funciona. Eu descobri que a melhor solução era criar um novo objeto Bitmap a partir da imagem que foi carregada do fluxo de memória. Dessa forma, o fluxo pode ser descartado, por exemplo
Espero que isto ajude.
fonte
Ocorreu um erro devido à permissão. verifique se a pasta possui TODA A PERMISSÃO.
fonte
RESOLVIDO - Eu tive esse problema exato. A correção, para mim, foi aumentar a cota de disco para o IUSR no servidor IIS. Nesse caso, temos um aplicativo de catálogo com imagens de itens e coisas do gênero. A cota de upload para o "Usuário da Web anônimo" foi definida como 100 MB, que é o padrão para os servidores IIS desta empresa de hospedagem. Aumentei para 400 MB e consegui enviar imagens sem erros.
Talvez esse não seja o seu problema, mas se for, é uma solução fácil.
fonte
No meu caso, o problema estava no caminho que eu estava salvando (a raiz
C:\
). Mudá-lo paraD:\111\
fazer a exceção desaparecer.fonte
Outra causa para esse erro - o caminho que você indica no método Save da instância de Bitmap não existe ou você não forneceu um caminho completo / válido.
Só tive esse erro porque estava passando um nome de arquivo e não um caminho completo!
Acontece!
fonte
Minha vez!
Consegui no .Save ... porque o using () está mantendo o arquivo aberto, então não posso substituí-lo. Talvez isso ajude alguém no futuro.
fonte
Mesmo problema que eu estava enfrentando. Mas no meu caso, eu estava tentando salvar um arquivo na unidade C e não estava acessível. Então, eu tentei salvar no drive D, que era totalmente acessível e consegui.
Portanto, verifique primeiro as pastas nas quais você está tentando salvar. Você deve ter todos os direitos (leitura e gravação) para essa pasta específica.
fonte
Percebo que o seu caso "jpeg" é realmente:
Tem certeza de que o formato é JPEG e não outra coisa?
Eu tentaria:
Ou verifique o que
imageToConvert.MimeType()
realmente está retornando.ATUALIZAR
Existe alguma outra inicialização que você precisa fazer no objeto MemoryStream?
fonte
fonte
Apenas para lançar outra solução possível na pilha, mencionarei o caso em que encontrei essa mensagem de erro. O método
Bitmap.Save
lançaria essa exceção ao salvar um bitmap que eu havia transformado e estava exibindo. Eu descobri que isso não causaria a exceção se a declaração tivesse um ponto de interrupção, nem oBitmap.Save
precederia,Thread.Sleep(500)
então suponho que haja algum tipo de contenção de recursos em andamento.Simplesmente copiar a imagem para um novo objeto Bitmap foi suficiente para impedir que essa exceção apareça:
fonte
Tivemos um problema semelhante ao gerar uma
PDF
imagem ou redimensionar usando o ImageProcessor lib no servidor de produção.Recicle o pool de aplicativos, corrija o problema.
fonte
Se você estiver tentando salvar uma imagem em um local remoto, adicione a
NETWORK_SERVICE
conta do usuário nas configurações de segurança e conceda a ele permissões de leitura e gravação. Caso contrário, não vai funcionar.fonte
fonte
Também recebo esse erro porque estou tentando salvar imagens com o mesmo nome das imagens salvas anteriores.
Certifique-se de não salvar imagens com nome duplicado.
Use, por exemplo, uma função 'Aleatória' ( Como o gerador de números aleatórios do C # funciona? ) Ou, por exemplo, gere um Guid ( http://betterexplained.com/articles/the-quick-guide-to-guids/ )
fonte
Simples, criar uma nova instância do Bitmap resolve o problema.
fonte
Para mim, eu estava usando o
Image.Save(Stream, ImageCodecInfo, EncoderParameters)
e, aparentemente, isso estava causando oA generic error occurred in GDI+
erro infame .Eu estava tentando usar
EncoderParameter
para salvar os jpegs em 100% de qualidade. Isso estava funcionando perfeitamente na "minha máquina" (doh!) E não na produção.Quando usei o
Image.Save(Stream, ImageFormat)
lugar, o erro desapareceu! Assim, como um idiota, continuei a usar o último, embora ele os salve na qualidade padrão, que eu presumo ser apenas 50%.Espero que esta informação ajude alguém.
fonte
Eu também encontrei o problema. O problema ocorreu devido ao descarte do fluxo de carregamento. Mas eu não a descartei, estava dentro da estrutura .Net. Tudo o que eu precisava fazer era usar:
ao invés de
image_instance é do tipo System.Windows.Forms.PictureBox! O PictureBox's Load () descarta o fluxo do qual a imagem foi carregada, e eu não sabia disso.
fonte
Com base na resposta de @savindra, se você RHM no seu aplicativo e tentar executar como administrador , deverá resolver o seu problema.
O meu parecia ser um problema de permissão.
fonte
Os possíveis problemas que causam esse erro são:
Espero que isso ajude, essa foi a correção do meu problema. Simplesmente verifiquei se o diretório de saída existe antes de salvar a imagem de saída!
fonte