Skip to content

Instantly share code, notes, and snippets.

@perlmonk
Last active Dec 6, 2015
Embed
What would you like to do?
Recover Images from Lightroom Previews, inspired by http://photo.bragit.com/Lightroom/articles/RecoverFromPreview.shtml
#!/usr/bin/perl
# 从lrprev里截取图片
use strict;
use warnings;
# single file
my $file = '/path/to/Lightroom x Catalog Previews.lrdata/x/x/id.lrprev';
my $dest = '/path/to/jpeg/prefix';
convert($file, $dest);
# all files
my $path = '/path/to/Lightroom x Catalog Previews.lrdata';
my $dst_path = '/path/to/jpeg/';
recovery_path($path);
sub recovery_path {
my ($path) = @_;
opendir DH, $path;
my @files = readdir(DH);
closedir DH;
foreach my $file(@files) {
next if $file =~ m{^\.{1,2}$}xmsi;
my $full = "$path/$file";
if (-d $full) {
print "处理文件夹$full\n";
recovery_path($full);
} else {
convert($full, "$dst_path/$file");
}
}
}
sub convert {
my ($src, $dst) = @_;
open FIN, '<', $src or die $!;
my $data;
while (<FIN>) {
$data .= $_;
}
close FIN;
$/ = '';
if ($data =~ m{AgHg(.*?)AgHg}xmsi) {
my $json = $1;
#print "json $json\n";
my @sizes = ();
while ($json =~ m/height\s=\s(\d+).*?width\s=\s(\d+)/xmsg) {
push @sizes, { h => $1, w => $2};
}
# 跳过levels = {
my $pos = index($data, 'levels');
my $idx;
do {
$idx = index($data, 'level_', $pos);
if ($idx >= 0) {
my $from = $idx + 8;
$pos = $idx + 1;
my $to = index($data, 'AgHg', $pos);
my $size = shift @sizes;
# skip small images(you can simple skip this by comment if pair)
if ($size->{w} >= 1500 || $size->{h} >= 1500) {
# 跳过小图
#next if (@sizes > 0); # 写最后一个文件
my $file .= "$dst-$size->{w}x$size->{h}.jpeg";
print "write $pos, $to to $file\n";
open FOUT, '>', $file or die $!;
binmode FOUT;
print FOUT ($to == -1 ? substr($data, $from) : substr($data, $from, $to-$from));
close FOUT;
}
}
} while ($idx != -1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment