# ExtractTagImagesCol - Adds a CoverArt column, and the commands ExtractTagImages and ExtractTagImage # # --- EXTRACTTAGIMAGE # INFILE is the input file # OUTFILE is the output file (including extension) # AUTOEXT attempts to autocorrect the file extension of the output file (png, jpg, gif) # the output filename must have an initial fileextension. # -- EXTRACTTAGIMAGES # OUTPATH specifies the output path for the files # AUTOEXT attempts to autocorrect the file extension of the output file (png, jpg, gif) use v5.14; use warnings; use strict; use Win32::OLE; use Win32::OLE qw(in valof CP_UTF8 CP_ACP OVERLOAD); use warnings qw(FATAL utf8); use utf8; use Win32::OLE::Variant qw(Variant VT_BSTR); Win32::OLE->Option(Warn => 3, CP => CP_UTF8); use MP3::Tag; my $useLogging=0; sub Log{ my $msg=shift; if ($useLogging){ $::DOpus->Output($msg); } } sub OnInit{ my $initData=shift; my $cmd; my $col; $initData->{name} = "ExtractTagImagesCol"; $initData->{desc} = "Extract images from tags in selected files"; $initData->{copyright} = "myarmor"; $initData->{version}="0.2.1"; $initData->{default_enable}=1; return 0; } sub OnAddColumns{ my $addColData=shift; my $col; # Call the addColData.AddColumn method once for each column you wish to add. $col = $addColData->AddColumn(); $col->{name} = "CoverArt"; $col->{method} = "OnCoverArt"; $col->{label} = "CoverArt"; $col->{autogroup} = 0; $col->{namerefresh}=1; $col->{justify} = "left"; # $col->{defwidth}=100; } sub OnAddCommands{ my $addCmdData=shift; my $cmd; # Call the addCmdData.AddCommand method once for each command you wish to add. $cmd = $addCmdData->AddCommand(); $cmd->{desc} = "Extract coverart for selected files into the same folder (appending _output to the name), or to a specific path"; $cmd->{hide} = 0; $cmd->{icon} = "info"; $cmd->{label} = "ExtractTagImages"; $cmd->{method} = "OnExtractTagImages"; $cmd->{name} = "ExtractTagImages"; $cmd->{template} = "OUTPATH/O,AUTOEXT/O"; $cmd = $addCmdData->AddCommand(); $cmd->{desc} = "Extract coverart from a file"; $cmd->{hide} = 0; $cmd->{icon} = "info"; $cmd->{label} = "ExtractTagImage"; $cmd->{method} = "OnExtractTagImage"; $cmd->{name} = "ExtractTagImage"; $cmd->{template} = "INFILE/K,OUTFILE/K,AUTOEXT/O"; } sub MimeToExt{ my ($mime,$filename)=@_; if ($mime=~m/png/i){ $filename=~s/\.[^.]+$/.png/; } elsif ($mime=~m/gif/i){ $filename=~s/\.[^.]+$/.gif/; } elsif ($mime=~m/jpeg/i){ $filename=~s/\.[^.]+$/.jpg/; } return $filename; } sub ExtractImage{ my ($infile,$outfile,$autoext)=@_; my $id3v2; Log("Extract image from ".$infile); my $mp3 = MP3::Tag->new($infile) or return 0; my $mime; # Get the tags from the MP3 $mp3->get_tags; if (exists $mp3->{ID3v2}){ $id3v2 = $mp3->{ID3v2}; # Get the APIC frame from the Tag (The Image) which # returns a hash ref my $Pic = $id3v2->get_frame("APIC"); if ($Pic){ if ($autoext){ $mime=$$Pic{'MIME type'}; Log("Mime: ".$mime); $outfile=MimeToExt($mime,$outfile); Log("New filename: ".$outfile); } open (SAVE, ">".$outfile); binmode SAVE; print SAVE $Pic->{_Data}; close SAVE; Log("Coverart found: ".$infile); return 1; } else{ Log("NO coverart found: ".$infile); } } else{ Log("NO ID3v2 tag found: ".$infile); } return 0; } sub HasCoverArt{ my ($infile)=@_; my $id3v2; Log("Check if ".$infile." has cover art"); my $mp3 = MP3::Tag->new($infile) or return 0; # Get the tags from the MP3 $mp3->get_tags; if (exists $mp3->{ID3v2}){ Log("ID3v2 exists"); $id3v2 = $mp3->{ID3v2}; # Get the APIC frame from the Tag (The Image) which # returns a hash ref my $Pic = $id3v2->get_frame("APIC"); if ($Pic){ Log("Coverart found: ".$infile); return 1; } else { Log("NO coverart found: ".$infile); return 0; } } else{ Log("NO ID3v2 tag found: ".$infile); return 0; } } # Implement the ExtractTagImages command sub OnExtractTagImages{ my $scriptCommandData=shift; my $filename; my $mi; my $Data; my $outpath; my $outfile; my $autoext; #disable deselect Log("ExtractTagImages"); $scriptCommandData->func->command->{deselect}=0; if ($scriptCommandData->func->args->got_arg->{outpath}){ $outpath=$scriptCommandData->func->args->{outpath}; Log("Outpath: ".$outpath); } if ($scriptCommandData->func->args->got_arg->{autoext}){ $autoext=$scriptCommandData->func->args->{autoext}; Log("Autoext: ".$autoext); } else { $autoext=0; } foreach my $item (in ($scriptCommandData->func->sourcetab->selected)){ if ($outpath ne ''){ $filename=valof $item->realpath; $outfile=$outpath."\\".$item->name; $outfile=~ s/\.[^.]+$/.jpg/; ExtractImage($filename,$outfile,$autoext); } else { $filename=valof $item->realpath; $outfile=$filename; $outfile=~ s/\.[^.]+$/.jpg/; ExtractImage($filename,$outfile,$autoext); } } } # Implement the ExtractTagImages command sub OnExtractTagImage{ my $scriptCommandData=shift; my $filename; my $mi; my $Data; my $outfile; my $infile; my $autoext; Log("ExtractTagImage"); #disable deselect $scriptCommandData->func->command->{deselect}=0; if ($scriptCommandData->func->args->got_arg->{infile}){ $infile=$scriptCommandData->func->args->{infile}; Log("Input file: ".$infile); } if ($scriptCommandData->func->args->got_arg->{outfile}){ $outfile=$scriptCommandData->func->args->{outfile}; Log("Output file: ".$outfile); } if ($scriptCommandData->func->args->got_arg->{autoext}){ $autoext=$scriptCommandData->func->args->{autoext}; Log("Autoext: ".$autoext); } else { $autoext=0; } if (($infile ne '') && ($outfile ne '')){ Log("Extracting coverart.."); ExtractImage($infile,$outfile,$autoext); Log("Done."); } } # Handler for the CoverArt column sub OnCoverArt{ my $scriptColData=shift; if ($scriptColData->{col}!="CoverArt"){ return; } if ($scriptColData->item->{is_dir}) { $scriptColData->{value} = ""; $scriptColData->{sort} = 3; } else { if (HasCoverArt($scriptColData->item->{realpath})==1){ $scriptColData->{value} = "Yes"; } else { $scriptColData->{value} = "No"; } } } 1;