Logicielsmoto.com
http://www.logicielsmoto.com/phpBB/

Convertion images & photos
http://www.logicielsmoto.com/phpBB/viewtopic.php?f=3&t=383
Page 7 sur 11

Auteur:  Prehisto [ 16 Sep 2015, 11:16 ]
Sujet du message:  Re: Convertion images & photos

Bon, ça, c'est facile, c'est le nombre de couleurs (3x16), je suppose ?

Auteur:  Samuel Devulder [ 16 Sep 2015, 11:50 ]
Sujet du message:  Re: Convertion images & photos

Oui mais pas 3*16, mais 12*4 car 12+4=16 (avec 3 et 16 ca dépasse).

C'est en effet un nombre de couleur que l'on voit à l'écran. On peut afficher des images en 48 couleurs sur thomson à la résolution 160x100.

L'idée est d'assembler 4 niveaux de bleu avec 3 niveaux de vert donc 12 couleurs bleu-vert, avec 4 niveaux de rouge sur 2 lignes. Une ligne contient bleu+vert, et l'autre rouge seul. C'est un peu la technique de 216i, mais même avoir besoin de flipper les écrans. En effet les 2 lignes vert/bleu rouge se mélangent très bien à l'écran, et pour même mieux les mélanger on peut échanger les 2 pixels alternativement pour chaque colonne.

Bref ca semble très prometteur. Le programme PERL effectue une conversion de fichiers VIDEO en gif animé à ce format, et le truc étonnant, c'est que ca marche aussi pour des image fixe type BMP ou jpg.

La résolution 160x100 peut sembler basse, mais en pratique ca marche bien, et les pixels y sont carrés ce qui facilite la transformation d'image.

Auteur:  Samuel Devulder [ 17 Sep 2015, 18:41 ]
Sujet du message:  Re: Convertion images & photos

Voilà ce à quoi ca ressemble pour des images:
Fichier(s) joint(s):
Avatar_The_Movie1.gif
Avatar_The_Movie1.gif [ 10.86 Kio | Vu 5081 fois ]
Fichier(s) joint(s):
_44417686_horse2.gif
_44417686_horse2.gif [ 8.59 Kio | Vu 5081 fois ]
Fichier(s) joint(s):
4bbc1a1956b3e05e667233f0debd5b70cb7fb5fc2aea9d7aec9e5e01a76aee0d_.gif
4bbc1a1956b3e05e667233f0debd5b70cb7fb5fc2aea9d7aec9e5e01a76aee0d_.gif [ 11.1 Kio | Vu 5081 fois ]

Mais le plus impressionnant ce sont les gifs animés
ImageImage
ImageImage

Auteur:  Prehisto [ 18 Sep 2015, 07:51 ]
Sujet du message:  Re: Convertion images & photos

Samuel Devulder a écrit:
Mais le plus impressionnant ce sont les gifs animés
Ah ouais, quand même :eek:
Tu présentes quelque chose comme ça à la Forever Party ? Ça va les clouer, c'est sûr :)

Auteur:  Samuel Devulder [ 18 Sep 2015, 08:04 ]
Sujet du message:  Re: Convertion images & photos

Il faut creuser l'idée. Il y a plusieurs challenges dont en particulier la commutation fond/forme qui va tuer les performances. Et il y a aussi le matériel supplémentaire qui fait que ce n'est pas thomson 100%, mais sur une petite animation de 4secs qui tient dans 512ko, c'est imaginable.

Petit clin d'oeil:
Image
(12Mo le gif. Il va falloir amméliorer la compression)

Auteur:  Samuel Devulder [ 04 Oct 2015, 00:26 ]
Sujet du message:  Re: Convertion images & photos

J'ai amélioré l'algo de conversion. D'une part, au lieu de prendre des niveaux rouges verts bleus identiques pour toutes les images, ils sont dorénavant étalonnés pour chaque image. En outre avec le découpage 3*4+4=16 précédent il y a deux fois le noir dans la palette. Si on les fusionne, on peut libérer un niveau de vert supplémentaire. On a ainsi 3 bleus, 4 rouges, et 5 verts. Le nombre de couleurs visibles à l'écran sans tramage monte alors à 3*4*5=60.

Avec ces 60 couleurs dont les niveaux sont spécialement adaptés à chaque image, le rendu est bien meilleur. Jugez donc:
Fichier(s) joint(s):
Avatar_The_Movie1.gif
Avatar_The_Movie1.gif [ 10.04 Kio | Vu 5050 fois ]
Fichier(s) joint(s):
_44417686_horse2.gif
_44417686_horse2.gif [ 8.32 Kio | Vu 5050 fois ]
Fichier(s) joint(s):
4bbc1a1956b3e05e667233f0debd5b70cb7fb5fc2aea9d7aec9e5e01a76aee0d_.gif
4bbc1a1956b3e05e667233f0debd5b70cb7fb5fc2aea9d7aec9e5e01a76aee0d_.gif [ 8.88 Kio | Vu 5050 fois ]

Voici le code pour les curieux:
Code:
#/bin/perl
#
# tst_bm16.pl - Conversion video en gif 15 couls 160x200.
#
# par Samuel DEVULDER, Sept-Oct 2015.
#

$file = $ARGV[0];
exit unless -f $file;

$name = $file; $name =~ s/\.[^\.]*$//;
$name=~s/.*[\/\\]//; $name = "out/$name.gif";
exit if -e $name;
mkdir("out");

# params par defaut
mkdir("tmp");
$img_pattern = "tmp/img%05d.bmp";
($w, $h) = (160, 100); # 16:9
$fps = 5;
$dither = "bayer4";
$zigzag = 0;

# recherche la taille de l'image
($x,$y, $aspect_ratio) = (160,100,"16:9");
open(IN, "./ffmpeg -i \"$file\" 2>&1 |");
while(<IN>) {
   if(/, (\d+)x(\d+)/) {
      ($x,$y) = ($1, $2);
      # 4:3
      if(abs($x - 4/3*$y) < abs($x - 16/9*$y)) {
         ($w,$h,$aspect_ratio) = (133,100,"4:3");
      }
   }
}
close(IN);
$h = int(($w=160)*$y/$x);
$w = int(($h=100)*$x/$y) if $h>100;

print "\n",$file," : ${x}x${y} ($aspect_ratio) -> ${w}x${h}\n";

# tuyau vers ffmpeg pour images
open(FFMPEG,'| (read line; $line)');#  -vf format=gray
binmode(FFMPEG);

# fichier video (entree)
open(IN, "<$file");
binmode(IN);

# détermination des parametres de dither
open(DITHER_O,"| ./ffmpeg -i - -v 0 -r 1 -s ${w}x${h} -an $img_pattern");
open(DITHER_I, "<$file");
binmode(DITHER_I);
binmode(DITHER_O);

# init image magick
&magick_init;

# parametres de dither
&dither_init(\*DITHER_I, \*DITHER_O, $dither, $w, $h);


# determination du zoom optimal
$cmd = "./ffmpeg -i - -v 0 -r $fps -s ${w}x${h} -an $img_pattern\n";
syswrite(FFMPEG, $cmd, length($cmd));

# nettoyage
unlink(<tmp/img*.bmp>);

# multiplicateur audio
@audio_cor = (8, 255);

# compteur image
$cpt = 1;

# ecran courant
$gif = Image::Magick->new(size=>"320x200");
$start = time;
$pause = 60;
while(1) {
   my $img = &next_image(\*IN, \*FFMPEG, $w, $h);
   last unless $img;

   #$img->Write("out/toto.png");
   $img->Set(dispose=>"None");
   $img->Set(delay=>int(100/$fps));
   push(@$gif, $img);
   undef $img;
   
   # infos à l'écran
   if($cpt%$fps == 0) {
      ++$time;
      my($d) = time-$start+.0001;
      print STDERR sprintf("%d:%02d:%02d (%.2gx)        \r",
         int($time/3600), int($time/60)%60, $time%60,
         int(100*$time/$d)/100);
      # pour ne pas trop faire chauffer le CPU
      if($d>$pause) {$pause = $d+60;sleep(10);}
   }

      
   # pas plus de 3000 imgs (5mins)
   last if $cpt==3000;
}

# ecriture du fichier gif
$gif->Set(dispose=>"None");
$gif->Set(Layers=>"optimize-trans");
$gif->Set(delay=>int(100/$fps));
$z=$gif->Write($name); print "$name: $z\n" if $z;
print STDERR "\n";
unlink(<tmp/img*.bmp>);

sub tune_image {
   my($tmp) = @_;
   
   $tmp->Modulate(saturation=>120); # un peu plus de couleurs
   $tmp->Evaluate(operator=>'Multiply', value=>255/245);
}

# Lit l'image suivante. Retourne 1 si ok, 0 si fin fichier
sub next_image {
   my($IN, $OUT, $w, $h) = @_;
   # nom du fichier BMP
   my $name = sprintf($img_pattern, $cpt++);
   my $tmp = Image::Magick->new();

   if($file =~ /\.(jpg|jpeg|png|bmp)$/i || $file=~/\.gif$/i && (-s $file)<=500*1024) {
      return 0 if $cpt==3;
      my $z = $tmp->Read($file);
      print STDERR "$z" if $z;
      return 0 if $z; # si erreur => fin fichier
      $tmp->Resize(geometry=>"${w}x${h}");
   } else {
      # taille fichier BMP
      my $expected_size = $h*(($w*3 + 3)&~3) + 54; # couleur

      #print "$w, $h, $expected_size\n";

      # on nourrit ffmpeg jusqu'a obtenir un fichier BMP fini
      while($expected_size != -s $name) {
         my $buf;
         my $read = read($IN,$buf,1634);
         last unless $read;
         syswrite $OUT, $buf, $read;
      }
      
      # lecture image
      my $z = $tmp->Read($name);
      #print STDERR $z if $z;
      return 0 if $z; # si erreur => fin fichier
      unlink $name if $name ne $file;
   }
   
   # dither
   $tmp->Set(depth=>16);
   $tmp->Set(colorspace=>$LINEAR_SPACE);
   &tune_image($tmp);
   my $img=Image::Magick->new(size=>"160x100");
   $img->Read("xc:black");
   $img->Composite(image=>$tmp, operator=>"Over", x=>(160-$w)>>1, y=>(100-$h)>>1);
   my @px = $img->GetPixels(height=>100, normalize=>"True"); undef $tmp; undef $img;
   for my $c (@px) {$c = int($c*255);}
   $dR = sub {
      my($v, $d,$a,$b) = @_;
      my($k) = "$v,$d";
      my $t = $glb_dR{$k};
      return $t if defined $t;
         
      $d /= $mat_x*$mat_y+1.0;
      ($a,$b) = ($lin_pal[$RED2],$lin_pal[$RED3]);
      return $glb_dR{$k}=(($v-$a)/($b-$a)>=$d ? $teo_pal[$RED3] : $teo_pal[$RED2]) if $v>=$a;
   
      ($a,$b) = ($lin_pal[$RED1],$a);
      return $glb_dR{$k}=(($v-$a)/($b-$a)>=$d ? $teo_pal[$RED2] : $teo_pal[$RED1]) if $v>=$a;
   
      ($a,$b) = ($lin_pal[$RED0],$a);
      return $glb_dR{$k}=(($v-$a)/($b-$a)>=$d ? $teo_pal[$RED1] : $teo_pal[$RED0]);
   } unless $dR;
   $dG = sub {
      my($v, $d,$a,$b) = @_;
      my($k) = "$v,$d";
      my $t = $glb_dG{$k};
      return $t if defined $t;
   
      $d /= $mat_x*$mat_y+1.0;
      ($a,$b) = ($lin_pal[$GRN3],$lin_pal[$GRN4]);
      return $glb_dG{$k}=(($v-$a)/($b-$a)>=$d ? $teo_pal[$GRN4] : $teo_pal[$GRN3]) if $v>=$a;
   
      ($a,$b) = ($lin_pal[$GRN2],$a);
      return $glb_dG{$k}=(($v-$a)/($b-$a)>=$d ? $teo_pal[$GRN3] : $teo_pal[$GRN2]) if $v>=$a;
   
      ($a,$b) = ($lin_pal[$GRN1],$a);
      return $glb_dG{$k}=(($v-$a)/($b-$a)>=$d ? $teo_pal[$GRN2] : $teo_pal[$GRN1]) if $v>=$a;
   
      ($a,$b) = ($lin_pal[$GRN0],$a);
      return $glb_dG{$k}=(($v-$a)/($b-$a)>=$d ? $teo_pal[$GRN1] : $teo_pal[$GRN0]);
   } unless $dG;
   $dB = sub {
      my($v, $d,$a,$b) = @_;
      my($k) = "$v,$d";
      my $t = $glb_dB{$k};
      return $t if defined $t;
   
      $d /= $mat_x*$mat_y+1.0;
      ($a,$b) = ($lin_pal[$BLU1],$lin_pal[$BLU2]);
      return $glb_dB{$k}=(($v-$a)/($b-$a)>=$d ? $teo_pal[$BLU2] : $teo_pal[$BLU1]) if $v>=$a;
   
      ($a,$b) = ($lin_pal[$BLU0],$a);
      return $glb_dB{$k}=(($v-$a)/($b-$a)>=$d ? $teo_pal[$BLU1] : $teo_pal[$BLU0]);
   } unless $dB;
   local @px2 = (0)x(3*320*200);
   $pset = sub {
      my($x,$y, $r,$g,$b) = @_;
      my($p)=($y*320+$x)*6;
      my($q)=$p+320*3;
      ($p,$q)=($q,$p) if $zigzag && ($x&1);
      @px2[$p..$p+5] = (0,$g,0,  0,$g,0);
      @px2[$q..$q+5] = ($r,0,$b, $r,0,$b);
   } unless $pset;
   
   for my $y (0..99) {
      for my $x (0..159) {
         my($d) = $mat[$x%$mat_x][$y%$mat_y];      
         my(@p) = splice(@px, 0, 3);
         $pset->($x,$y, $dR->($p[0],$d),$dG->($p[1],$d),$dB->($p[2],$d));
      }
   }
   return &px2img(320,200,@px2);
}

sub dither_init {
   my($in, $out, $dither, $w, $h) = @_;
   
   my $expected_size = $h*(($w*3 + 3)&~3) + 54;

   # param dither
   @mat = ([1]);
   @mat = ([1,3],
         [4,2]) if $dither eq "bayer2";
   @mat = ([7,8,2],
         [6,9,4],
         [3,5,1]) if $dither eq "sam3";
   @mat = ([3,7,4],
         [6,1,9],
         [2,8,5]) if $dither eq "3x3";
   @mat = ([6, 9, 7, 12],
         [14, 3, 15, 1],
         [8, 11, 5, 10],
         [16, 2, 13, 4]) if $dither eq "vac4";
   @mat = ([1,9,3,11],
         [13,5,15,7],
         [4,12,2,10],
         [16,8,14,6]) if $dither eq "bayer4";
   @mat = ([21,2,16,11,6],
         [9,23,5,18,14],
         [19,12,7,24,1],
         [22,3,17,13,8],
         [15,10,25,4,20]) if $dither eq "vac5";
   @mat = ([35,57,19,55,7,51,4,21],
         [29,6,41,27,37,17,59,45],
         [61,15,53,12,62,25,33,9],
         [23,39,31,49,2,47,13,43],
         [3,52,8,22,36,58,20,56],
         [38,18,60,46,30,5,42,28],
         [63,26,34,11,64,16,54,10],
         [14,48,1,44,24,40,32,50]) if $dither eq "vac8";
   $mat_x = 1+$#mat;
   $mat_y = 1+$#{$mat[0]};
   
   @teo_pal = (0,100,127,142,163,179,191,203,215,223,231,239,243,247,251,255);
   @lin_pal = (0, 33, 54, 69, 93,115,133,152,173,188,204,220,229,237,246,255);

   my @pc2teo = ();
   for my $i (1..$#teo_pal) {
      my($a,$b,$c) = ($teo_pal[$i-1],($teo_pal[$i-1]+$teo_pal[$i])>>1,$teo_pal[$i]);
      for my $j ($a..$b)   {$pc2teo[$j] = $i-1;}
      for my $j ($b+1..$c) {$pc2teo[$j] = $i;}
   }
   
   my @tabR = (0)x16;
   my @tabG = (0)x16;
   my @tabB = (0)x16;
   
   if($file =~ /\.(jpg|jpeg|png|bmp)$/i || $file=~/\.gif$/i && (-s $file)<=500*1024) {
      close($in);close($out);
      my $img = Image::Magick->new();
      my $x = $img->Read($file); die "$x, stopped $!" if $x;
      $img->Resize(geometry=>"${w}x${h}");
      &tune_image($img);   
      # trammage
      my @px = $img->GetPixels(height=>$h, normalize=>"True");
      undef $img;
      for(my $i=0; $i<$#px; $i+=3) {
         ++$tabR[$pc2teo[int($px[$i+0]*255)]];
         ++$tabG[$pc2teo[int($px[$i+1]*255)]];
         ++$tabB[$pc2teo[int($px[$i+2]*255)]];
      }   
   } else {
      my $time = 1;
      my $run = 1;
      while(1) {
         my $name = sprintf($img_pattern, $time);
         if($expected_size != -s $name) {
            last unless $run;
            my $buf;
            my $read = read($in,$buf,163840);
            if($read) {
               syswrite $out, $buf, $read;
            } else {
               $run = 0;
               close($out);
            }
         } else  {
            # image complete!
            print STDERR $time++,"s\r";
         
            # lecture de l'image
            my $img = Image::Magick->new();
            my $x = $img->Read($name); die "$x, stopped $!" if $x;
            unlink $name if $name ne $img_pattern;
            &tune_image($img);

            if(!defined $pal4096) {
               my @px;
               for my $r (0..15) {
                  for my $g (0..15) {
                     for my $b (0..15) {
                        push(@px, $teo_pal[$r], $teo_pal[$g], $teo_pal[$b]);
                     }
                  }
               }
               $pal4096 = &px2img(256,16, @px);   
            }
            #$img->Remap(image=>$pal4096, dither=>"true", "dither-method"=>"Floyd-Steinberg");
         
            # trammage
            my @px = $img->GetPixels(height=>$h, normalize=>"True");
            undef $img;
            for(my $i=0; $i<$#px; $i+=3) {
               ++$tabR[$pc2teo[int($px[$i+0]*255)]];
               ++$tabG[$pc2teo[int($px[$i+1]*255)]];
               ++$tabB[$pc2teo[int($px[$i+2]*255)]];
            }   
         }
      }
      close($in);close($out);
      unlink(<tmp/img*.bmp>);
   }
      
   my $f = sub {
      my($name, @t) = @_;
      my($tot, $acc, $max, @r);
      my(@tab) = splice(@t,0,16);
      for my $t (@tab) {$max = $t if $t>$max; $tot += $t;}
      
      $r[0] = -1; my($z) = $tot;
      for my $t (@t) {
         for(my $i=$r[$#r]+1; $i<16; ++$i) {
            $acc += $tab[$i];
            if($acc>=$t*$z) {
               $z-=$acc; $acc=0;
               push(@r, $i);
               last;
            }
         }
      }
      shift @r;

      if($#r!=$#t) {
         my($deb,$fin)=($r[0], $r[$#r]);
         $z = $tot;
         for my $i (0..$deb)  {$z -= $tab[$i];}
         for my $i ($fin..15) {$z -= $tab[$i];}
         @r = ($deb);
         for my $t (@t[1..$#t-1]) {
            for(my $i=$r[$#r]+1; $i<16; ++$i) {
               $acc += $tab[$i];
               if($acc>=$t*$z) {
                  $z-=$acc; $acc=0;
                  push(@r, $i);
                  last;
               }
            }
         }
         push(@r, $fin);
         @r = sort { $a <=> $b } @r;
      }
      
      for my $i (0..$#tab) {print sprintf("%s%2d:%3d%% %s\n", $name, $i, int(100*$tab[$i]/($tot+1)), "X"x(int(50*$tab[$i]/($max+1))));}
      print join(' ', @r),"\n";
      return @r;
   };
   
   # ($RED0, $RED1, $RED2, $RED3) = $f->("RED", @tabR, 0.02, 0.33, 0.66, 0.95);
   # ($GRN0, $GRN1, $GRN2, $GRN3) = $f->("GRN", @tabR, 0.02, 0.33, 0.66, 0.95);
   # ($BLU0, $BLU1, $BLU2)        = $f->("GRN", @tabR, 0.02,    0.50,    0.95);
   ($GRN0, $GRN1, $GRN2, $GRN3,$GRN4) = $f->("GRN", @tabG, 0.0, 0.20, 0.20, 0.50, 0.85);
   ($RED0, $RED1, $RED2, $RED3)       = $f->("RED", @tabR, 0.0, 0.20, 0.50,       0.85);
   ($BLU0, $BLU1, $BLU2)              = $f->("BLU", @tabB, 0.0,    0.50,          0.85);
}

sub px2img {
   my($width,$height,@px) = @_;
   
   open(PX2IMG,">/tmp/.toto2.pnm");
   print PX2IMG "P6\n$width $height\n255\n",pack('C*', @px),"\n";
   close(PX2IMG);
   my $img2 = Image::Magick->new();
   $img2->ReadImage("/tmp/.toto2.pnm");
   unlink "/tmp/.toto2.pnm";
   return $img2;
}

sub magick_init {
   if(!$_magick) {
      $_magick = 1;
      eval 'use Image::Magick;';
      # determination de l'espace RGB lineaire
      my $img = Image::Magick->new(size=>"256x1", depth=>16);
      $img->Read('gradient:black-white');
      $img->Set(colorspace=>'RGB');
      #$img->Set(colorspace=>"Gray") unless $coul;
      my @px1 = $img->GetPixel(x=>128, y=>0);
      $img->Read('gradient:black-white');
      $img->Set(colorspace=>'sRGB');
      #$img->Set(colorspace=>"Gray") unless $coul;
      my @px2 = $img->GetPixel(x=>128, y=>0);
      my $d1 = $px1[0]-0.5; $d1=-$d1 if $d1<0;
      my $d2 = $px2[0]-0.5; $d2=-$d2 if $d2<0;
      $LINEAR_SPACE = $d1>=$d2 ? "RGB" : "sRGB";
      #print $px1[0], "   ",$px2[0],"    $LINEAR_SPACE\n";
   }
}

Auteur:  Prehisto [ 04 Oct 2015, 07:48 ]
Sujet du message:  Re: Convertion images & photos

Effectivement, la répartition des points est plus homogène. Ça s'améliore, ça s'améliore :good:

Auteur:  Samuel Devulder [ 16 Oct 2016, 14:32 ]
Sujet du message:  Re: Convertion images & photos

Le code ci-dessus est inutilisable sans l'environnement de developpement adapté. C'est nul :colere: :q

Aussi, j'ai fait un script LUA pour Grafx2 qui implémente le même algorithme mais qui est nettement plus simple à installer et à utiliser. Les résultat du script n'est pas trop mal sauf un petit soucis avec la taille finale de l'image que je n'arrive pas à positionner à 320x200 de façon programmée en fin de script (c'est un bug qui me dépasse dans l'usage de l'api LUA de GrafX2). Mais c'est pas si grave.

A noter que certaines images truecolor sont initialement converties bizzarement en 256 couleurs par l'algo de grafx2. On y voit de gros à-plats de couleurs uniformes, cf le visage sur la 1ere capture ci-dessous. Je soupçonne que l'algo de lecture d'image et de réduction de couleur utilisé par GrafX2 de ne pas bien corriger le gama et que du coup il n'y ait pas assez de couleurs libres pour les basses intensités. Mais bon ca n'empêche pas l'algo de conversion de bien se dépatouiller quand même. Voyez par vous même et experimentez!
Fichier(s) joint(s):
Image1.png
Image1.png [ 213.96 Kio | Vu 4365 fois ]
Fichier(s) joint(s):
Image2.png
Image2.png [ 42.11 Kio | Vu 4365 fois ]

[edit]upate du programme de conversion. Sauvegarde en MAP à coté de l'image d'origine + production d'une image 320x200 pret à sauver en GIF.

Fichiers joints:
Commentaire: Conversion d'image true-color en BM16 thomson sous GrafX2
bayer4_bm16.zip [6.58 Kio]
Téléchargé 177 fois

Auteur:  PulkoMandy [ 16 Oct 2016, 16:01 ]
Sujet du message:  Re: Convertion images & photos

Je confirme que l'algo de réduction de couleurs ne fait pas de correction gamma. S'il y a des gens intéressés pour l'améliorer, le code se trouve ici:

http://pulkomandy.tk/projects/GrafX2/br ... p_c.c#L777

En entrée, on a une "table d'occurence" des couleurs utilisées dans l'image. On utilise l'algorithme du median cut (enfin je crois, même pas sur que ça soit implémenté correctement).

On pourrait commencer par changer l'espace de couleurs de la table d'occurences, puis convertir la palette obtenue à la fin par l'opération inverse?

Une fois que le choix de la palette est terminé, il y a un deuxième problème: le choix des couleurs pour la conversion 24b>256 couleurs. On utilise pour ça, la table de conversion remplie par CT_set, qui mappe un "pavé" de l'espace RGB vers une couleur située au centre de ce pavé (toujours dans l'espace RGB). Je ne sais pas si c'est la meilleure solution.

On a choisi de ne pas faire de diffusion d'erreur car le but est surtout d'importer une image comme base de travail.

Auteur:  Samuel Devulder [ 25 Oct 2016, 00:38 ]
Sujet du message:  Re: Convertion images & photos

Bon j'ai trouvé le work-around du setpicturesize() qui me causait soucis. Du coup à présent on a bien une image 320x200 en fin de conversion prête à être sauvée en GIF. J'ai aussi ammélioré le programme puisqu'à présent il sauve une fichier MAP juse à coté du fichier source. Il n'est donc plus besoin de passer par un convertisseur externe GIF->MAP. Enfin, j'ai un peu mieux structuré le programme, me laissant la possibilité d'ajouter d'autres modules de conversion plus tard.

Voici quelques exemples de conversion de peintures de l'artiste Boris Vallejo
Fichier(s) joint(s):
BorisVallejo.gif
BorisVallejo.gif [ 9.2 Kio | Vu 4337 fois ]
Fichier(s) joint(s):
BorisVallejo2.gif
BorisVallejo2.gif [ 11.89 Kio | Vu 4337 fois ]
Fichier(s) joint(s):
Boris Vallejo 1980 - 05.gif
Boris Vallejo 1980 - 05.gif [ 8.62 Kio | Vu 4337 fois ]


A votre tour essayer le programme et de publier ici les meilleures conversions :love:

Auteur:  PulkoMandy [ 25 Oct 2016, 06:17 ]
Sujet du message:  Re: Convertion images & photos

On peut récupérer la dernière version quelque part?
Et deuxième question, sous quelle license est-il diffusé, et est-ce qu'on peut l'inclure dans les prochaines versions de GrafX2?

Auteur:  Samuel Devulder [ 25 Oct 2016, 08:34 ]
Sujet du message:  Re: Convertion images & photos

Elle est dans le zip ci-dessous (était ci-dessus, mais cette version bug un peu au niveau du gamma). Je l'ai mise sous GPL (comme les autres scripts je crois).

Par ailleurs je vais essayer de porter un autre algo que j'ai découvert permettant de faire du tramage "bayer" sur du mode 40 colonne standard. Ca change de la diffusion d'erreur déjà présentée (skyrim, etc). Ainsi on pourra facilement ajouter de jolies images dans n'importe quelle production thomson.

Auteur:  Samuel Devulder [ 25 Oct 2016, 23:36 ]
Sujet du message:  Re: Convertion images & photos

Samuel Devulder a écrit:
Par ailleurs je vais essayer de porter un autre algo que j'ai découvert permettant de faire du tramage "bayer" sur du mode 40 colonne standard. Ca change de la diffusion d'erreur déjà présentée (skyrim, etc). Ainsi on pourra facilement ajouter de jolies images dans n'importe quelle production thomson.
Bon ben, c'est fait, voir le zip ci-joint. C'est le programme bayer4_mo5.lua.
Fichier(s) joint(s):
BorisVallejo.gif
BorisVallejo.gif [ 5.68 Kio | Vu 4317 fois ]
Fichier(s) joint(s):
BorisVallejo2.gif
BorisVallejo2.gif [ 7.47 Kio | Vu 4317 fois ]

A noter: ce zip contient bayer4_to8.lua qui est une version corrigée du précédent bayer4_bm16.lua. En effet ce dernier ne tenait pas compte de la correction gamma et produisait des images trop claires. Cependant je pense que je dois encore améliorer l'algorithme car j'ai réussi à obtenir bien mieux avec une maquette. Donc ca n'est pas encore la version finale de la conversion en BM16 ;)
[EDIT1] C'est fait. J'ai un nouvel algo BM16 donnant encore plus souvent de meilleur résultats. L'archive ci-dessous a été mise à jour en conséquence.
[EDIT2] j'ai modifié la routine de sauvegarde au format MAP pour sauver en plus les données brutes (RAMA, RAMB, Palette) à coté du fichier map lorsqu'on appuie shift-ESC lors des sauvegardes (commencer par shift lors de la selection du programme de conversion ou durant la boite de confirmation d'écrasemement, puis terminer par ESC durant la conversion). On peut donc récupérer les données mémoire pour traitement ultérieure (compression EXOMIZER par exemple).


Fichiers joints:
Commentaire: bayer4_mo5 (40 colonnes) et bayer4_to8 (BM16)
thomson.zip [10.09 Kio]
Téléchargé 186 fois

Auteur:  W_oo_d [ 28 Oct 2016, 16:19 ]
Sujet du message:  Re: Convertion images & photos

Awesome pictures :love:

Great job Sam :)

Auteur:  Samuel Devulder [ 14 Nov 2016, 02:08 ]
Sujet du message:  Re: Convertion images & photos

Thanks :)

Bon quelques nouvelles sur ce sujet.. Il y a eu pas mal d'ammélioration dans mes algos ces derniers jours (vive les ponts!)
  • Ammélioration de la fonction de dé-gamma-ification qui fait que l'on colle à présent parfaitement avec le gamma de l'image source. En particulier les couleurs sombres apparaissent vraiment sombre sans être éclaircies par le trammage :D Pour ceux que ca intérésse, j'utilise à présent la formule de https://fr.wikipedia.org/wiki/SRGB#Tran ... on_inverse qui marche nettement mieux que celle (originale) de https://en.wikipedia.org/wiki/Rec._709
  • Portage de mon algo (efficace) de réduction de palette depuis perl vers lua (grafx2). Il est rapide et donne des résultats très corrects
  • Portage de mon adaptation dithering du type diffusion d'erreur à coefficients variable de Victor Ostromoukhov. En combinant cela avec la palette issue du point précédent j'ai une conversion 160x200x16 pas du tout moche. :D
  • Adaptation de l'algo de dither ci-dessus au cas de la présence de color-clash. L'algo s'en sort vraiment très bien, mais est super lent (3mins par image dans le pire des cas avec un PC d'il y a 10ans). Je dois regarder cela de plus près, mais les images 320x200x16 avec contraintes obtenues sont mimi comme tout, que ce soit avec une palette adaptée générée par l'algo du point 2, mais de façon encore plus surprenante avec la palette de 16 couleurs thomson standard.
Bon c'est tout pour ce soir (cette nuit!) car le concert de Sting se termine. Je posterais sans doute des images plus tard pour illustrer ce que j'entends pas "par pas du tout moche" et "mimi comme tout", mais normalement ca dépote bien.

Page 7 sur 11 Heures au format UTC + 1 heure
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/