2011-01-10 5 views
3

간단한 메시지 기반 시스템을 만드는 중입니다. 각 메시지는 jpeg 이미지이며, 프로그램이로드 될 때 (사용자가 로그온 한 직후) 도트 JPG는 무작위로 선택되어 표시됩니다. 사용자가 다음 버튼을 클릭하면 모든 jpg가 표시 될 때까지 다른 jpg가 표시됩니다. 각 이미지를 배열로 읽어서 배열에서 하나를 무작위로 선택한 다음 사용자가 다음을 클릭하여 배열의 다음 항목으로 이동할 필요가 있다고 생각합니다. 하나주의해야 할 점은 다른 사람들이 삭제할 수 있어야하므로 프로그램에서 jpg 파일을 열지 못하게하는 것입니다.C# 이미지를 무작위로 하나씩 표시합니다.

현재 코드가 아래에 있으므로 도움과 조언을 보내 주시면 감사하겠습니다.

private void Form1_Load(object sender, EventArgs e) 
{ 
     var rand = new Random(); 
     var files = Directory.GetFiles(@"\\server\screens\", "*.jpg"); 
     pictureBox1.Image = System.Drawing.Bitmap.FromFile(files[rand.Next(files.Length)]); 
} 

private void buttonNextImage_Click(object sender, EventArgs e) 
{ 
     var rand = new Random(); 
     var files = Directory.GetFiles(@"\\server\screens\", "*.jpg"); 
     pictureBox1.Image = System.Drawing.Bitmap.FromFile(files[rand.Next(files.Length)]); 
} 

많은 감사 스티븐 여기

+0

정확히 당신이 게시 코드에 어떤 문제가 있습니까? – Blorgbeard

+0

현재 코드가 파일을 잠그고 이미지 배열을 만드는 방법을 모르겠습니다. 감사합니다. –

+0

지적 할 가치가있는 한 가지는 ...'rand.Next'를 사용하면 배열의 모든 파일을 검사하지 않을 가능성이 있습니다. 셔플/무작위 배정에 관해서는 [내 대답은 아래를 참조하십시오] (http://stackoverflow.com/questions/4645704/c-display-images-randomly-and-one-after-another/4645955#4645955)를 참조하십시오. . –

답변

3

Bitmap.FromFile를 사용하지 마십시오입니다 Bitmap.FromStream를 사용 : 나는 이미지의 배열을 만드는 방법을 모르는

using(var fs = new FileStream(files[rand.Next(files.Length), 
           FileMode.Open, FileAccess.Read)) 
{ 
    pictureBox1.Image = System.Drawing.Bitmap.FromStream(fs); 
} 

var files = Directory.GetFiles("\\\\server\\screens\\", "*.jpg"); 
var images = new Image[files.Length]; 
for(int i = 0; i < files.Length; ++i) 
{ 
    using(var fs = new FileStream(files[i], FileMode.Open, FileAccess.Read)) 
    { 
     images[i] = System.Drawing.Image.FromStream(fs); 
    } 
} 
+0

안녕하세요,이 잘 작동하지만 동일한 이미지를 두 번 이상 표시하는 방법이 문제를 해결할 수 있습니까? 감사합니다 –

+0

나는 편집 권한이 없지만 코드의 첫 번째 줄은 오른쪽 대괄 문자가 누락되어 있고 읽어야한다고 생각합니다 : (var fs = new FileStream (files [rand.Next (files.Length)], FileMode .Open, FileAccess.Read)) – joeschwa

2

두 가지 : 그것은 한 번만 인스턴스화 줘야 있도록

    는 클래스 멤버로에서 무작위로 인스턴스를 이동
  1. .
  2. 이미지를 표시 한 후 표시된 이미지 만 목록에 남아 있도록 파일 배열에서 이미지를 제거하십시오. 목록이 비어 있으면 모두 표시했음을 알 수 있습니다.
0

Øyvind Bråthen의 답변을 확대하면 모든 사진이 표시되면 어레이를 재설정 할 수 있으며 타이머를 사용할 수 있으므로 이미지가 자동으로 변경됩니다.

a) 귀하가 (메모리 스트림으로 최악의 옵션을 JPG 파일을로드) :

0

나는 당신이이 옵션을했습니다 있다고 생각합니다.

b) "tmp"와 같은 이름과 접미사 (예 : "1.tmp.jpg")와 같은 이름 및 임시 파일을 만듭니다.

"b"를 직접 가져 와서 복사본을 만든 후에는 클래스 수준에서 임의로 표시하려는 파일의 색인을 만듭니다.

그런 다음 매 시간마다 이미지를 변경하기 위해 일종의 타이머를 사용합니다.

마지막으로 모든 틱 이후에 파일 경로 배열을 동기화하여 프로그램에 최신 및 최신 파일을 표시 할 수 있습니다.

내 제안 :

0

팁 목록 :

  • 그림 배열을 만들지 마십시오. 이미 표시 한 파일 이름을 HashSet<string>으로 만드십시오. 그런 다음 NEXT을 클릭하면 폴더를 반복하여 이미 표시된 파일 이름을 무시합니다. 남아있는 것 (있는 경우)에서 무작위로 하나를 선택하십시오.이렇게하면 런타임에 폴더 내용이 변경 되더라도 여전히 대부분의 내용을 얻을 수 있습니다. 그리고 한 번에 모든 이미지를로드하여 메모리를 낭비하지 않습니다.
  • 사진을 표시 할 때 바로 넣으십시오. Clone() 그 다음에 Dispose() 원본을로드하십시오. 그렇게하면 파일을 잠그지 않습니다.
  • 다음 이미지를 표시 할 때 리소스를 확보하기 위해 이전 이미지를 Dispose() (을)를 잊지 마세요.
0

다음은 일반적인 요청 방법입니다.

  1. 로드 배열로 (샘플에서, \\Server\Screens\) 원하는 디렉토리에있는 모든 JPEG 파일.

  2. 파일 배열을 무작위 화하십시오. 다음은 배열을 셔플하는 샘플 구현입니다. Most efficient way to randomly shuffle a list of integers

  3. 배열의 첫 번째 그림을로드하십시오. 배열에는 분명히 파일 이름이 포함되어 있으므로 PictureBox의 Image 속성을 원하는 요소로 지정할 수 없습니다. 이미지를로드해야합니다.

    이미지를 잠글 필요가 없으므로 스트림에서 이미지를로드하는 것이 좋습니다 (@max's answer 참조).

  4. 사용자가 다음 버튼을 클릭하면 다음 사진을로드합니다. 귀하의 질문부터 파일이 존재하는지 확인해야합니다. 사용자가로드되기 전에 파일을 삭제할 수 있다고 추론합니다.

0
public static int id = 0; 
private void timer1_Tick(object sender, EventArgs e) 
{ 
    id = id + 1; 
    filelocation = "E:\\example\\" + id + ".bmp"; 
    pictureBox1.Image = System.Drawing.Bitmap.FromFile(filelocation); 
} 
+0

이 코드 샘플은 솔리드 설명과 함께 사용하면 훨씬 더 유용 할 것입니다. –

관련 문제