Component to preview files in a directory

Ask about the individual Gambas components here.
01McAc
Posts: 75
Joined: Sunday 24th January 2021 8:25pm

Component to preview files in a directory

Post by 01McAc »

I know there is the main component gb.form which provides the FileView class. Unfortunately, fileview does not preview all files (e.g. photo raw files) but Dolphin and Nautilus do preview these files. Dolphin uses qt5 so in return I would expect to find another fileview component in gb.qt5*- but there isn't. Does anybody know another component in Gambas to show and preview files?
User avatar
BruceSteers
Posts: 1521
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Component to preview files in a directory

Post by BruceSteers »

qt5 can read a few formats but to read more the code has to be added to your application. that's what the other programs have done.

If you want to preview more files like nautilus and others then you will have to write the code as they have.
If at first you don't succeed , try doing something differently.
BruceS
User avatar
BruceSteers
Posts: 1521
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Component to preview files in a directory

Post by BruceSteers »

Or think of it this way...

it probably safe to assume that where gambas only uses the FileView qt widget other applications like Nautilus that are essentially one big FileView application have written their own complete file viewer control and do not just rely on the generic qt built in one.

Hope that makes sense
:roll:
If at first you don't succeed , try doing something differently.
BruceS
User avatar
stevedee
Posts: 518
Joined: Monday 20th March 2017 6:06pm

Re: Component to preview files in a directory

Post by stevedee »

Pretty much as I said on the 14th March, you need to find a utility (e.g. simple command-line program, or maybe a library) that you can utilise to do this task.

I suggest you take a look at Phil Harvey's Exiftool as this has an argument called JpgFromRaw and can be used in batch mode. So I'm suggesting you extract jpeg files from all RAWs in a directory, save them in /tmp directory (so as not to clog up your hard drive) then display each one as required.

But my preference would be to look at LibRaw, as this has a nice looking C API that you could declare in Gambas (https://www.libraw.org/docs/API-C.html).

Maybe its;

Code: Select all

int libraw_unpack(libraw_data_t*);
function would do what you need.

By using LibRaw you may end up with some useful code that others could use when working with RAWs in Gambas.

For exiftool there is a friendly forum: https://exiftool.org/forum/index.php
User avatar
cogier
Site Admin
Posts: 1118
Joined: Wednesday 21st September 2016 2:22pm
Location: Guernsey, Channel Islands

Re: Component to preview files in a directory

Post by cogier »

Steve pointed me to the ExifTool, but I could not get the -JpgFromRaw to work. I did get the -PreviewImage to work. Have a look at the attached code with the following provisos:-

1/. You need to have the exiftool installed.
2/. My camera is a Canon 6D Mark II and the raw format is CR2, so this is the file type I tested this on.
3/. The program has no error catching code.
TestNew-0.0.8.tar.gz
(11.8 KiB) Downloaded 262 times
01McAc
Posts: 75
Joined: Sunday 24th January 2021 8:25pm

Re: Component to preview files in a directory

Post by 01McAc »

Thanks guys for all your advice and code.
stevedee wrote: Sunday 21st March 2021 10:23am For exiftool there is a friendly forum: https://exiftool.org/forum/index.php
Indeed this have been a helpful knowledge base for me. Attached is the alpha version of my tool. I use (of course) exiftool. A marvelous little program but cumbersome with all the parameters.
cogier wrote: Sunday 21st March 2021 3:39pm but I could not get the -JpgFromRaw to work
I did- but -JpgFromRaw generates big files with original image size. What I actual need is just a tiny thumbnail. The parameter -PreviewImage generates a ~500kb file and a size of 1.440x960 which is actually too big for my purpose. exiftool cannot generate resized images out of a raw file, unfortunately. A pipe to another tool like imagemagick would be possible but all in all it takes too much time for a simple preview. Since I use exiftool my tool works for all supported raw files incl. CR2. The main focus is to view the GPS location on a map. The program has no error catching code either.
stevedee wrote: Sunday 21st March 2021 10:23am Maybe its;

Code: Select all

int libraw_unpack(libraw_data_t*);

function would do what you need.
Interesting you are mentioned this. I stumbled upon the libraw library earlier and looked for an example how to use libraries in general and libraw specifically. I had no luck and didn't find something so I went back to exiftool.
stevedee wrote: Sunday 21st March 2021 10:23am Have a look at the attached code with the following provisos:
Ultimately we have the same approach how to handle raw file. So I guess it is the right one;)
Attachments
ExifLocation-0.0.1.tar.gz
(15.92 KiB) Downloaded 260 times
User avatar
stevedee
Posts: 518
Joined: Monday 20th March 2017 6:06pm

Re: Component to preview files in a directory

Post by stevedee »

01McAc wrote: Sunday 21st March 2021 6:41pm... I stumbled upon the libraw library earlier and looked for an example how to use libraries in general and libraw specifically...
Don't know if you are still interested, but as its a poor TV night, I thought I'd take a look.

Turns out that the libraw C-API plays nice with Gambas.
'Just some demo code using the C-API of library: libraw
'Only needs libraw, a Gambas Form and a PictureBox
'
'steve davis 23-Mar-2021
'================================================

Library "libraw:16"

Public Extern libraw_init(iflags As Integer) As Pointer   'initialisation
Public Extern libraw_close(libraw_data_t As Pointer)
Public Extern libraw_version() As String
Public Extern libraw_open_file(libraw_data_t As Pointer, sFileName As String) As Integer
Public Extern libraw_unpack_thumb(libraw_data_t As Pointer) As Integer
Public Extern libraw_dcraw_thumb_writer(libraw_data_t As Pointer, sFileName As String) As Integer

Const RAW_FILE_NAME As String = "sample1.dng"   'a sample RAW image file
Const THUMB_FILE_NAME As String = "s1Thumb.jpg"   'the small extracted jpeg version


Public Sub Form_Open()
Dim pPoint As Pointer
Dim intReply As Integer
Dim strThumbNail As String
  
  'delete last demo image
  strThumbNail = Application.Path & "/" & THUMB_FILE_NAME
  If Exist(strThumbNail) Then
    Kill strThumbNail
  Endif
  
  'the fun starts here!
  pPoint = libraw_init(0)
  Me.Text = "libraw: " & libraw_version()
  intReply = libraw_open_file(pPoint, Application.Path & "/" & RAW_FILE_NAME)
  If intReply < 1 Then
    intReply = libraw_unpack_thumb(pPoint)
    If intReply < 1 Then
      intReply = libraw_dcraw_thumb_writer(pPoint, strThumbNail)
      If intReply < 1 Then
        pBox.Image = Image.Load(strThumbNail)
      Endif
    Endif
  Endif
  libraw_close(pPoint)

End
...or download the project which includes a sample RAW file (.DNG)
RAW_file.tar.gz
(6.02 MiB) Downloaded 256 times
Although this extracts a 'thumbnail', this image has a resolution of 1024 x 683 for a file size of about 100k.

EDIT

I just found that with an Olympus RAW (.ORF) the thumbnail is much larger with a higher resolution.
Also, you should add
pBox.Stretch = True
to the code above (& project file) after the image is loaded to the PictureBox.
01McAc
Posts: 75
Joined: Sunday 24th January 2021 8:25pm

Re: Component to preview files in a directory

Post by 01McAc »

stevedee wrote: Tuesday 23rd March 2021 7:37pm Don't know if you are still interested
Yes, I am. The code is exactly what I was looking for. What I can do is just copy and paste the code but, to be honest, I don't understand how a (any) library must be declared. How did you figure that out?

Re the poor TV night: how about a good book or going out for photography (night shooting with available light)? Helping people in the forum here might be a better idea:)
User avatar
stevedee
Posts: 518
Joined: Monday 20th March 2017 6:06pm

Re: Component to preview files in a directory

Post by stevedee »

01McAc wrote: Wednesday 24th March 2021 3:57pm
stevedee wrote: Tuesday 23rd March 2021 7:37pm Don't know if you are still interested
...What I can do is just copy and paste the code but...

....I don't understand how a (any) library must be declared. How did you figure that out?
Its better not to just copy any of my examples...its much better to understand how its working and then write your own code better than my simple examples!

Here is the process I followed to establish what needed to be declared;
Knowing that libraw supported a C API, I opened Synaptic package manager and searched for libraw (If you also have a Debian/Ubuntu based Linux distro, this will make sense).
Although I had a package called: libraw1394 this was clearly nothing to do with RAW files. The only other package listed (and it was already installed) was: libraw16 described as a RAW image decoder library.
Initially I declared in Gambas;
Library "libraw"
Public Extern libraw_init(iflags As Integer) As Pointer
...but when I tried to run libraw_init in my code I got an error, something like;

Code: Select all

Cannot find dynamic library libraw.so
...where file.so is usually the library you are looking for.

So then I tried declaring the library as libraw16, but got a similar message.
Third-time-lucky when I declared: libraw:16
This format is basically using ":16" to define a kind of version. I say "kind of" because the actual version is reported as: 0.18.8
...but never let the facts get in the way of celebrating a 'success'

I then checked and verified that I was talking to this library by using the most basic function, declared and used something like this;
Public Extern libraw_version() As String
strVersion = libraw_version()
I covered the declaration of functions from a C API in a recent post: https://forum.gambas.one/viewtopic.php?p=4051#p4051 but if you have more questions, just ask.

Just how you decide to implement this solution will (I hope) be your choice, as I can't see much point in providing highly polished code. After all, you want to write code, not simply copy-and-paste what others dish up. But I will give a little bit of general advice. As your programs get bigger, it makes sense to take a modular approach.

I've taken my own example and moved the code into a Module called LibRAW, as the only stuff in a Form class should be code that is directly related to the Form. Here are two simple functions in this module;
Public Function initialisation() As Boolean
  'returns True if initialisation is successful
  
  pDataStructure = libraw_init(0)
  If Not IsNull(pDataStructure) Then
    Return True
  Endif
  
End

Public Function version() As String
  
  Return libraw_version()
  
End
This makes using the library code in Gambas, more Gambas-like;
Public Sub Form_Open()

  If LibRAW.initialisation() Then
    Me.Text = "LibRaw version: " & LibRAW.version()
    LibRAW.CloseLibraw()
  Endif
End
...its a bit like a Gambas wrapper for the C library libraw...although not a great example.

I hope some of this nonsense helps!

Further reading:-
https://captainbodgit.blogspot.com/2019 ... aries.html
https://gambaswiki.org/wiki/howto/extern


Re the poor TV night: how about a good book or going out for photography (night shooting with available light)? Helping people in the forum here might be a better idea:)
Thanks for the tips.
I'm reading quite a bit at the moment and having a love affair with my 3D Printer. Like most love affairs, its about 50% fantastic and about 50% rubbish.

Its currently a bit too cold for my fragile body to venture out after dark. But I hope to re-build my strength and regain control of my body's thermostat in the very near future!
01McAc
Posts: 75
Joined: Sunday 24th January 2021 8:25pm

Re: Component to preview files in a directory

Post by 01McAc »

Lots of investigation, thank you Sherlock :) I'll go through it in the next days.
Post Reply