2012-02-03 3 views
2

지금 당장 PictureBox 컨트롤에 많은 미리보기 이미지를로드하는 응용 프로그램이 있습니다. 때때로 한 번에 백 개가 넘는 경우가 있습니다. 이미지는 Image.FromStream (MemoryStream)을 사용하여 만들어지며 메모리 스트림은 각 JPG 파일을 나타냅니다.이미지로드 및 스트림/파일 종속성

현재 Image.FromStream을 호출하자마자 스트림을 Flush() 및 Dispose() 한 직후에 그림 상자에 대한 참조를 지정합니다.

설명서에 따르면 이미지를 다 끝낼 때까지 스트림을 풀어서는 안됩니다. 그러나, 나는 이것을하는 어떤 오류도 가지지 않고 있었다. My PictureBox 컨트롤은 메모리 스트림이 오랫동안 삭제 된 후에도 축소판 이미지로 하루 종일 다시 칠할 수 있습니다.

그러나 저장 기능을 호출하는 것과 같은 방법으로 이러한 이미지에 액세스하려고하면 오류가 발생합니다.

  • 비트 맵에 메모리 스트림이나 파일 스트림이있는 경우 처리 할 때 해당 소스를 처리합니까? 아니면 Bitmap.FromFile을 사용하여 스트림 자체를 생성 할 때만입니까?

  • 내가 좋아하는 것으로 간주하는 것처럼 즉시 MemoryStream을 삭제합니까? PictureBox는 어떤 방식 으로든 이미지를 캐싱해야합니다. 이미지가 설정되면 이미지를 만질 필요가 없으므로 오류가 발생하지 않습니다.

부모 컨트롤에 그림을 그리려면 오랜 시간이 걸립니다. 너무 많은 컨트롤이 있거나 이미지가 PictureBox에 처음 칠 때 지연이 있기 때문에 이것이 맞는지 잘 모르겠습니다.

파일 매개 변수를 사용하여 새 비트 맵을 만들면 처음으로 필요할 때까지 실제로 파일 내용을로드하지 않는다는 것을 알고 있습니다. 내 문제는 각 OnPaint 작업이 파일 읽기에 의해 지연되는 것을 원하지 않는다는 것입니다. 컨트롤을 그리기 전에 데이터가 미리로드되는지 확인해야합니다. 그렇지 않으면 깜박 거리고 느린 페인팅이 발생합니다.

강제로 이미지를 미리로드하는 좋은 방법이 있습니까? Image.FromFile, Image.FromStream, 새 비트 맵 (fileName) 등의 불일치는 무엇입니까? 이 중 하나라도 즉시 모든 바이트를로드합니까? 아니면 처음으로 필요할 때까지 지연됩니까? 당신이 폐기 소스 처분한다, 비트 맵은 메모리 스트림 또는 파일 스트림에 대한 종속성이있는 경우

MemoryStream ms = new MemoryStream(bytes); // byte[] array 
pictureBox.Image = Image.FromStream(ms); 
ms.Flush(); 
ms.Dispose(); 

답변

1

Image 클래스의 기초가되는 GDI +는 이미지가 제대로 작동하는 동안 원본 스트림이 열려 있어야합니다. Image가 소스 스트림을 사용하는 동안 소스 스트림에 변경 사항을 쓰는 것도 나쁜 생각입니다. 변경 사항을 다른 스트림에 저장해야합니다.

이미지에서 파생 된 모든 것은 커버 아래 스트림을 사용합니다. 그들의 로딩 동작은 동일합니다.

이미지는 FromStream을 통해 제공된 스트림을 닫거나 처리하지 않습니다. 너 자신을 관리해야 해.

또한 스트림에서 플러시를 호출하면 스트림에 기록 된 경우에만 효과가 있습니다. 당신이 당신의 PictureBoxes에 대한 UI 동작을 개선하기 위해 찾고 있다면

,이 시도 :

  1. 설정 InitialImage을 작은 스피너 GIF로.
  2. WaitOnLoad를 false로 설정하십시오.
  3. ImageLocation을 설정하여 이미지를 지정하십시오. (파일 스펙이나 URL을 사용할 수 있습니다.)
  4. LoadAsync 메소드를 사용하여 이미지를 비동기 적으로로드하십시오.
0

1)

:

여기 내 코드입니까? 또는 Bitmap.FromFile을 사용하여 스트림 자체를 생성 할 때만입니까?

Image.FromStream Method (Stream, Boolean)에서보세요 :

당신은 이미지의 수명 오픈 스트림을 유지해야합니다.

2)

PictureBox를 어떤 방법으로 이미지를 캐싱해야합니다.한번 설정 한 이미지를 만질 필요가 없기 때문에 나는 을 본 적이 없습니다. PictureBox를이 사용하는 반면

당신은 (그것을 사용 즉 그림 상자) 그것이 PictureBox를에 할당 된 이후 이미지 인스턴스를 폐기하고 안된다. 그렇지 않으면 PictureBox는 폐기 된 이미지를 사용하려고 시도하고 "좋지 않은"결과를 초래합니다.

PictureBox.Image Property

: 당신이 다수의 PictureBox에 컨트롤을 동일한 이미지를 사용하는 각의 PictureBox에 대한 이미지의 복제를 만들려면

참고. 에 액세스하면 여러 컨트롤에서 동일한 이미지가 발생하여 예외가 발생합니다.

업데이트 : 실질적으로 동일한 시나리오

샘플 : HOW TO: Copy a Picture from a Database Directly to a PictureBox Control with Visual C#.

+0

테스트 결과를 읽었습니까? Image.FromStream에 사용 된 스트림을 처리했지만 아직 PictureBox 컨트롤은 여전히 ​​잘 페인팅되어 있습니다. 나는 PictureBoxes에서 최상의 성능을 얻는 방법을보다 잘 이해하기 위해 왜 이러한 일이 발생하는지 파악하려고 노력하고 있습니다. –

+0

@Moozhe, MemoryStream Dispose()는 ** MemoryStream 구현 때문에 메모리를 실제로 처리하지 않습니다 ** : 가비지 수집 될 간단한 바이트 배열을 사용합니다. FileStream 클래스로 실험 해보시겠습니까? –

+0

MemoryStream이 메모리를 할당하지 않았기 때문에 소리가 나옵니다. PictureBox는 가비지 수집을하지 않는 바이트 [] 배열의 메모리 주소에 대한 참조를 보유해야합니다. –