Salvando uma imagem modificada para o arquivo original usando GDI +
-
05-07-2019 - |
Pergunta
Eu estava carregando uma imagem de bitmap de um arquivo. Quando eu tentei salvar a imagem para outro arquivo Eu tenho o seguinte erro "Ocorreu um erro genérico em GDI +". Eu acredito que este é porque o arquivo está bloqueado pelo objeto de imagem.
Ok, então tentou chamar a função Image.Clone. Isso ainda bloqueia o arquivo.
hmm. Em seguida eu tente carregar uma imagem de bitmap de um FileStream e carregar a imagem na memória para GDI + não bloquear o arquivo. Isso funciona muito bem, exceto eu preciso gerar miniaturas usando método Image.GetThumbnailImage ele lança uma exceção de memória. Aparentemente eu preciso para manter o fluxo aberto para parar esta exceção, mas se eu manter o fluxo aberto, em seguida, os restos de arquivo bloqueado.
Assim, não é bom com esse método. No final, eu criou uma cópia do arquivo. Então agora eu tenho 2 versões do arquivo. 1 eu posso bloquear e manipular no meu programa c #. Este outro arquivo original permanece desbloqueado para que eu possa salvar modificações. Este tem a vantagem de permitir-me para reverter as alterações, mesmo depois de salvá-los, porque eu estou manipulando a cópia do arquivo que a mudança não pode.
Na verdade, há uma maneira melhor de conseguir isso sem ter que ter 2 versões do arquivo de imagem. Alguma idéia?
Solução 2
Eu tenho uma vez encontrado um método alternativo para clonar a imagem sem bloquear o arquivo. Bob Powell tem tudo isso acrescido de mais recursos GDI .
//open the file
Image i = Image.FromFile(path);
//create temporary
Image t=new Bitmap(i.Width,i.Height);
//get graphics
Graphics g=Graphics.FromImage(t);
//copy original
g.DrawImage(i,0,0);
//close original
i.Dispose();
//Can now save
t.Save(path)
Outras dicas
Bem, se você está procurando outras maneiras de fazer o que está pedindo, acho que ele deve trabalhar para criar um MemoryStream, e ler o FileStream a ele, e carregar a imagem de que o fluxo ...
var stream = new FileStream("original-image", FileMode.Open);
var bufr = new byte[stream.Length];
stream.Read(bufr, 0, (int)stream.Length);
stream.Dispose();
var memstream = new MemoryStream(bufr);
var image = Image.FromStream(memstream);
Ou algo mais bonita a esse ponto.
Seja ou não essa é a maneira que você deve ir sobre como resolver esse problema, eu não sei. :) Eu tive um problema semelhante e acabou fixando-o assim.
Eu tive um problema semelhante. Mas eu sabia, que eu vou salvar a imagem como um arquivo bitmap. Então eu fiz isso:
public void SaveHeightmap(string path)
{
if (File.Exists(path))
{
Bitmap bitmap = new Bitmap(image); //create bitmap from image
image.Dispose(); //delete image, so the file
bitmap.Save(path); //save bitmap
image = (Image) bitmap; //recreate image from bitmap
}
else
//...
}
Claro, isso não é a melhor maneira, mas o seu trabalho: -)