2013-08-11 1 views
1

나는 전체 스택   오버 플로우 전반에 걸쳐 수색,하지만 난 다음에 대한 답변을 찾을 수 없습니다 : 나는 닫습니다C#에서 OpenFileDialog를 삭제 하시겠습니까?

OpenFileDialog을 사용하고 있습니다 때, 나는 내 프로그램에서 사용하기 위해 차단됩니다 열려있는 파일까지를 내 프로그램. 따라서 이미지를 열면 더 이상 Windows Explorer에 해당 이미지를 바꿀 수 없습니다.

나는이 내 OpenFileDialog를를 배치하는 문제라고 생각합니다,하지만 난 그것을 해결하는 방법을 잘 모르겠어요 ...

내 코드 : 나는 using 블록이 해결할 것이라고 생각

using (OpenFileDialog ofd = new OpenFileDialog()) 
{ 
    ofd.Title = "Open Image"; 
    ofd.Filter = "PNG Image(*.png|*.png" + 
       "|GIF Image(*.gif|*.gif" + 
       "|Bitmap Image(*.bmp|*.bmp" + 
       "|JPEG Compressed Image (*.jpg|*.jpg"; 

    if (ofd.ShowDialog() == DialogResult.OK) 
    { 
     pictureBox1.Image = new Bitmap(ofd.FileName); 
    } 
} 

이 문제는 아니지만 ... 여전히 프로그램에서 사용됩니다. 픽처 박스에 이미지를로드하고 이미지를 다시 사용 가능하게하고 싶습니다 (이름을 바꿀 수 있고 바꿀 수 있습니다 ... 등).

답변

1

같은 것을 시도 :

pictureBox1.Image = Image.FromStream(new MemoryStream(File.ReadAllBytes(old.FileName))); 

그것은 File.ReadAllBytes 모든 파일을 읽고하는 MemoryStream에 넣어 정적 초기화자인 ImageMemoryStream을 전달합니다.

byte[] bytes = File.ReadAllBytes(old.FileName); 
MemoryStream ms = new MemoryStream(bytes); 
pictureBox1.Image = Image.FromStream(ms); 

당신은 MemoryStream을 버리지해야합니다에

등가!Image이 처분 될 경우 MemoryStream의 종료 자 (ms에 대한 다른 참조 정보가없는 경우)와 MemoryStream이 삭제됩니다 (이 내용은 즉시 발생하지 않습니다. GC가 실행될 때 일어날 일)

+0

고맙습니다. 나는 문자 그대로 당신의 코드 규칙을 복사했고 즉시 작업했습니다. 정말 고마워요! – Merlijn

+2

죄송합니다. 내 대답이 잘못되었습니다. 복사 가능 코드가 없습니다. 오 잘, 나에게 많이 일어난다. Bitmap을 복제하는 것이 MemoryStream을 누출하는 것보다 더 나은 옵션이라고 생각합니다. 이는 코드 검토를 거치지 않고 심하게 주석을 달아야합니다. 당신이 언급 한 것처럼, 그것은 매우 직관력이 없습니다. –

+0

@CodyGray +1을주었습니다.하지만 요점은 마지막 마일이 Chris (MemoryStream 클래스 사용)의 설명에 주어 졌다는 것입니다. 당신의 반응은 매우 "이론적"이었습니다. – xanatos

5

이것은 OpenFileDialog와 관련이 없습니다. 대화 상자가 실제로 파일을 열지 않기 때문에 가능하지 않습니다. 은 사용자가 파일을 열어을 선택한 다음 해당 경로를 사용자에게 반환하므로 파일을 여는 코드를 작성할 수 있습니다. 게다가, 당신은 정확히 using 문을 사용하여 OpenFileDialog를 처리하고 있습니다.

여기에서 문제는 실제로 파일 -을 열어 비트 맵으로 온 것입니다. the Bitmap constructor overload that accepts a path string을 사용하면 이미지가 포함 된 디스크의 파일이 Bitmap 개체가 삭제 될 때까지 잠긴 상태로 유지됩니다. 문서 :

파일은 비트 맵이 처리 될 때까지 잠긴 상태로 유지됩니다. 당신이 pictureBox1.Image에 비트 맵을 할당하고 있기 때문에 pictureBox1이 배치 될 때까지

, 비트 맵 객체는 배치되지 않습니다. 따라서 디스크의 이미지 파일은 잠긴 상태로 유지됩니다.

파일의 잠금을 해제하려면 비트 맵 복사본을 만들어 원본을 처리하거나 PictureBox를 지우고 작업을 마쳤 으면 이전 이미지를 삭제해야합니다.

나는 당신의 질문을 이해하기 때문에 그림 상자에 이미지를 계속 표시하면서 디스크의 이미지 파일을 변경할 수있는 것처럼 들린다. 그렇다면 복사본을 만들어야합니다. 이 같은 이미지를 취하는 생성자 오버로드를 사용하여 않는 것이 : 크리스가 쓴 것처럼

if (ofd.ShowDialog() == DialogResult.OK) 
{ 
    // Load the image the user selected 
    using (Image img = Image.FromFile(ofd.FileName)) 
    { 
     // Create a copy of it 
     Bitmap bmpCopy = new Bitmap(img); 

     // Clear out the bitmap currently in the picture box, 
     // if there is one. 
     if (pictureBox1.Image != null) 
     { 
      pictureBox1.Image.Dispose(); 
     } 

     // Assign the copy of the bitmap to the picture box. 
     pictureBox1.Image = bmpCopy; 
    } 
} 
+2

이것이 문제 일 수 있습니다. 나는 과거에 그것에 물렸다. 하나의 옵션으로 파일 바이트를 읽고 대신'MemoryStream'에서'Bitmap'을 생성 할 수 있습니다. –

+0

@Chris 스트림에서 파일을 잠그지 않았습니까? 스트림에서 생성 한 모든 Bitmap 객체의 수명 동안 스트림을 열어 두어야한다는 것을 기억하십시오. –

+0

당신은 모든 표를 얻었습니다. 당신은 정말로 당신의 대답을 고쳐야합니다. Bitmap.Clone()은 얕은 복사본을 만들고 원래 비트 맵의 ​​픽셀 데이터를 계속 사용합니다. 따라서 파일에 대한 잠금을 해제하지 않습니다. 내 대답을 자유롭게 사용하면 내 것을 삭제할 것입니다. –

0

내가 가장 잘 발견 한 기술은 File.ReadAllBytes() (파일을 열고 닫음)를 사용하여 바이트 배열로 파일을 읽은 다음 사용합니다 바이트 배열을 Image로 변환하는 ImageConverter 예를 들어 여기를 참조하십시오 : https://stackoverflow.com/a/16576471/253938

편집 : 이전 게시글의 견적에서 : "내가 시도한 다른 기술 중 일부는 픽셀의 비트 심도가 변경 되었기 때문에 최적이 아닙니다. 32 비트) 또는 이미지의 해상도 (dpi)를 무시합니다. "