Seite 1 von 2

DrawImage()-Problem

Verfasst: 02.02.2018 19:33
von DarkSoul
Ich habe ein Bild mit folgenden Eigenschaften:

- Komplett mit der Farbe Grün (#00FF00) gefüllt (das Original sieht etwas anders aus, aber bei einer Grünfläche tritt das Problem auch auf)
- Bitmap
- 4-Bit / 16 Farben
- 37x46 Pixel

Wenn ich dieses Bild mit LoadImage() lade und anschließend mit DrawImage() auf ein CanvasGadget rendere, ist links ein ein Pixel breiter roter Streifen (#0000FF). :|

Passiert auf Ubuntu 17.4 und Linux Mint 18.1 gleichermaßen, aber nicht auf Windows.

Wenn ich die Bittiefe auf 24 umstelle, verschwindet das Problem (aber das Format kann ich nicht mal eben wechseln, da es wegen vergangener Programm-Versionen "in Stein" gemeißelt ist. Zudem ist das Erhöhen der Bittiefe in meinem Fall sinnlos.)

PB-Bug? :roll:

Re: DrawImage()-Problem

Verfasst: 02.02.2018 19:58
von Mijikai
Wenn es einen TestSource gibt kann ich es gerne (zumindest) auf meinem System (Win 10) testen.

Re: DrawImage()-Problem

Verfasst: 02.02.2018 20:17
von DarkSoul
Wie bereits beschrieben, passiert das nicht unter Windows, sondern unter Linux.

Ich habe mal was zusammengeschoben, was das Problem veranschaulicht

Code: Alles auswählen

OpenWindow(0,0,0,640,480,"test")
CanvasGadget(0,0,0,640,480)
LoadImage(0, "ex.bmp")
StartDrawing(CanvasOutput(0))
DrawImage(ImageID(0),10,10)
StopDrawing()

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
(Bitte jetzt nicht meckern, dass im Beispiel die If's fehlen, die sicherstellen, dass alle Elemente auch verfügbar sind. :mrgreen: Daran liegt es nicht )

Und hier ein Bild dazu, mit dem das passiert: https://www.dropbox.com/s/zhdvzi0o1qtls3n/ex.bmp?dl=0

Re: DrawImage()-Problem

Verfasst: 04.02.2018 00:21
von ccode_new
Hallo "Dunkle Seele",

das Problem scheint aber auch nur bei 32 bit zu bestehen.

Scheint ein PureBasic-Bug zu sein.

Dieser simple C-SDL-Test stellt z.B. ein 32 bit BMP korrekt dar.

Code: Alles auswählen

#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>

static void display_bmp( const char *datei, SDL_Surface *screen,
                         int x, int y) {
  SDL_Surface *bild;
  SDL_Rect ziel;
  /* lädt die BMP-Datei in ein Surface */
  bild = SDL_LoadBMP(datei);
  if ( bild == NULL ) {
    fprintf(stderr, "'%s' konnte nicht geladen werden: %s\n",
       datei, SDL_GetError());
    return;
  }
  /* auf den Bildschirm kopieren                     */
  /* die Surfaces sollten hier nicht gelockt sein.   */
  /* x,y = linke obere Ecke; w, h = Breite und Höhe  */
  ziel.x = x;
  ziel.y = y;
  ziel.w = bild->w;
  ziel.h = bild->h;
  /* Neue Größe des Surfaces entsprechend der Bildgröße */
  screen = SDL_SetVideoMode (bild->w, bild->h,
                             16, SDL_SWSURFACE | SDL_RESIZABLE);
  if (screen == NULL) {
    printf ("Videomodus konnte nicht verändert werden: %s\n",
       SDL_GetError ());
    exit(EXIT_FAILURE);
  }
  SDL_BlitSurface(bild, NULL, screen, &ziel);
  /* den veränderten Bildschirmbereich auffrischen */
  SDL_UpdateRect(screen, 0, 0, 0, 0);
  SDL_FreeSurface(bild);
}
int main (int argc, char **argv) {
  SDL_Surface *screen;
  int i;
  if( argc == 1 ) {
    printf("Bitte mindestens eine BMP-Datei angeben!\n");
    return EXIT_FAILURE;
  }
  /* SDLs Videosystem initialisieren und auf Fehler prüfen */
  if (SDL_Init (SDL_INIT_VIDEO) != 0) {
    printf ("Konnte SDL nicht initialisieren: %s\n",
       SDL_GetError ());
    return EXIT_FAILURE;
  }
  /* Wenn die Anwendung beendet wird,          */
  /* wird die Funktion SDL_Quit() ausgeführt   */
  atexit (SDL_Quit);
  /* Videomodus mit 640 x 480 Pixel, Hi-Color (16 Bit) */
  /* einrichten. Oberfläche (Surface) standardmäßig    */
  /* in den Hauptspeicher (SDL_SWSURFACE) legen       */
  screen = SDL_SetVideoMode (640, 480, 16,
                             SDL_SWSURFACE|SDL_RESIZABLE);
  if (screen == NULL) {
    printf ("Videomodus konnte nicht eingerichtet werden: "
            " %s\n", SDL_GetError ());
    return EXIT_FAILURE;
  }
  /* Slideshow starten ...                                   */
  /* Zeigt alle BMP-Bilddateien an, die in der Kommandozeile */
  /* mit angegeben wurden                                     */
  for( i = 1; argv[i] != NULL; i++) {
    display_bmp(argv[i], screen, 0, 0 );
    SDL_Delay (4000);  
  }
  printf ("Erfolgreich beendet!\n");
  return EXIT_SUCCESS;
}
Aber ob das Problem vielleicht auch ein bei OpenGL bestehender Fehler ist habe ich noch nicht getestet.

Re: DrawImage()-Problem

Verfasst: 04.02.2018 00:52
von DarkSoul
Hier ist die Darstellung mit deinem Programm korrekt. Sowohl 4, 8, 24 als auch 32 Bit werden korrekt gezeigt und haben den Fehler nicht.
das Problem scheint aber auch nur bei 32 bit zu bestehen.
Ich habe ein 64-Bit Betriebssystem. :wink:

(Den Teil mit C (und damit an PB vorbei) zu programmieren, wäre natürlich eine Lösung... Aber nur, wenn es nicht anders geht. :mrgreen: )

Re: DrawImage()-Problem

Verfasst: 04.02.2018 08:47
von ccode_new
@DarkSoul

1. Ich meinte mit 32 bit die Farbtiefe beim Bild und nicht ob du ein 32 bit oder 64 bit OS hast. Kannst ja trotzdem mal die 32 bit Libs unter deinem 64 bit Linux nachinstallieren und die 32 bit Version von Purebasic installieren und probieren. Ich glaube aber kaum das es daran liegt.

2. Dein geliefertes Beispielbild ist aber ein 24 bit JPEG und kein BMP-Bild.
Dieses Bild wird von PureBasic korrekt dargestellt.

Wenn man nun das Bild mit z.Bsp. Gimp in ein 24 bit BMP konvertiert wird es immer noch unter PureBasic korrekt dargestellt.
Wenn man das Bild mit Gimp in ein 32 bit BMP konvertiert wird das Bild von Gimp oder einer anderen Gtk-Anwendung (mit GTK Canvas) korrekt dargestellt, aber unter PureBasic wird bei mir das gesamte Bild nur noch rot dargestellt. (BUG ?)

Re: DrawImage()-Problem

Verfasst: 04.02.2018 09:14
von Omi
Moin zusammen.

Es sieht tatsächlich nach einem Fehler in LoadImage() aus. 2 Quick&Dirty-Versuche zeigen zumindest, dass
die Übergabe des geladenen Bildes in ein ImageGadget() das selbe Problem hat.
Lädt man per API, ist die rote Zeile nicht vorhanden (nur auf Xubuntu 14.04/x32 + PB5.46 getestet, bitte Pfade anpassen ...):

Code: Alles auswählen

;linke Pixelreihe ist rot ...
OpenWindow(0,0,0,640,480,"test")

If LoadImage(0, "/home/charly/Programming/Programm/ex.bmp")
	ImageGadget(0, 10, 10, 37, 46, ImageID(0))
EndIf


Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

Code: Alles auswählen

;Anzeige okay ...
ImportC ""
	gdk_pixbuf_new_from_file(filename.p-utf8, *error.GError)
EndImport

Global *pixbuf

OpenWindow(0,0,0,640,480,"test")

*pixbuf= gdk_pixbuf_new_from_file("/home/charly/Programming/Programm/ex.bmp", @*error)
If Not *error
	ImageGadget(0, 10, 10, 37, 46, *pixbuf)
EndIf

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Grüße Charly
Nachtrag: Hab vergessen zu erwähnen, dass ich jetzt aus der Hüfte geschossen nicht sagen kann, wie sich die API-Variante bezüglich Farbtiefe verhält.

Re: DrawImage()-Problem

Verfasst: 04.02.2018 21:22
von DarkSoul
ccode_new hat geschrieben:@DarkSoul
2. Dein geliefertes Beispielbild ist aber ein 24 bit JPEG und kein BMP-Bild.
Dieses Bild wird von PureBasic korrekt dargestellt.
Es ist eine BMP-Datei.
Bitte auf Download klicken und nicht das Vorschaubild per Rechtsklick speichern. :)
ccode_new hat geschrieben: Wenn man das Bild mit Gimp in ein 32 bit BMP konvertiert wird das Bild von Gimp oder einer anderen Gtk-Anwendung (mit GTK Canvas) korrekt dargestellt, aber unter PureBasic wird bei mir das gesamte Bild nur noch rot dargestellt. (BUG ?)
Habe ich gerade ausprobiert. Der Bug tritt bei mir nicht auf. Ich habe stattdessen dasselbe Problem wie bei 4-Bit, jedoch mit dem Unterschied, dass der rote Streifen dann schwarz ist.

@Omi
Die API-Variante funktioniert bei mir auch störungsfrei. So ähnlich werde ich das erstmal workarounden <)

Re: DrawImage()-Problem

Verfasst: 11.02.2018 13:49
von DarkSoul
Hat vllt. jemand einen CatchImage()-Ersatz in Form von Linux-Api parat? Ich brauche nur den PixBuf-Zeiger, nicht die imageID. :mrgreen:

Vorkommende Eingabeformate sind:

BMP 4-bit
BMP 8-bit
PNG 1-bit
PNG 2-bit
PNG 4-bit
PNG 8-bit

Re: DrawImage()-Problem

Verfasst: 11.02.2018 18:11
von Omi
Hi DarkSoul,

ich hab mich mit dem direkten "Kapern" von Images noch nicht beschäftigt - vielleicht klingelt's auch grad nicht bzgl. möglicher Tricks - aber, falls sonst niemand was weiß und 'Eigenhilfe' fällig wird, wären hier möglicherweise passende API-Adressen (iss aber sischer etwas Beschäftigungstherapie :wink: ):
https://developer.gnome.org/gdk-pixbuf/stable/rn01.html
https://developer.gnome.org/gdk-pixbuf/ ... emory.html

Viel Glück, Charly