Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Cool Uses for Perl

( #1044=superdoc: print w/replies, xml ) Need Help??

This section is the place to post your general code offerings -- everything from one-liners to full-blown frameworks and apps.

CUFP's
Inline::CUDA : looking for feedback
No replies — Read more | Post response
by bliako
on Jul 28, 2021 at 05:52

    Hi all,

    I have placed a preliminary version of Inline::CUDA at https://github.com/hadjiprocopis/perl-inline-cuda, it has only been installed on my machine (Linux, GeForce 650). I would be grateful for comments from anybody who would try to install it in their machines: OSX, Windows, other Linux versions with different NVIDIA GPU versions.

    It's a lot of work to download the huge NVIDIA CUDA SDK and it is very likely that you will also need to install a specific compiler version (additional to your system compiler). So, be prepared to spend a few hours on it! I apologise!

    Hopefully, with your insight and feedback I will be able to create a better installation workflow. I have Alien::Build in mind.

    Comments and feedback on the actual code and style are very welcome as well.

    Many Thanks

    bw, bliako

Linux/Perl Cabrillo to ADIF Conversion Script
No replies — Read more | Post response
by jmlynesjr
on Jul 21, 2021 at 16:15

    Script to convert an Amateur Radio Cabrillo format log file into to an ADIF(Amateur Data Interchange Format) logfile.

    A Cabrillo file has space delimited fields. An ADIF file has tag delimited fields and field order is not important. A Cabrillo file is used for entry into Ham radio contests like the ARRL Field Day. ADIF files are used to import contact data into logging software like QRZ.com. This process was used to create(with QRZlogfmt.pl) a Cabrillo log of 200+ entries and then import this file into my log on QRZ.com. I prefer to log on paper and I will use this process to enter and import contact data as I fill a log sheet.

    Posted here so it can be found by the search engines. Other utilities that I have found are for Windows only.

    James

    There's never enough time to do it right, but always enough time to do it over...

Linux/Perl Cabrillo Logfile Creation Script
No replies — Read more | Post response
by jmlynesjr
on Jul 21, 2021 at 16:12

    Script to create a simple Amateur Radio Cabrillo Format Log File

    Not much out there for Linux users, had to roll my own. Log file created with 200+ entries then converted to ADIF format and uploaded to QRZ.com. Posted here so it can be found by the search engines.

    James

    There's never enough time to do it right, but always enough time to do it over...

Ajax voting and modern formatting on PerlMonks
No replies — Read more | Post response
by Your Mother
on Jul 18, 2021 at 20:23

    (I reserve the right to make *sensible* silent updates or corrections in code and formatting for a day or two; until I remove this line. No one wants a post that has ďupdate: ÖĒ repeated 20 times and if I have to proof this for an hour right now, I wonít post it.) :P

    This code will give the site a more modern layout and appearance. You can thank tobyink for that part.

    Fair warning

    This code was just written for me. Itís not bombproof, it has no automatic tests, and including external files is a security risk if the source/host decides to exploit it or is itself hacked. I only address problems as they arise so there may be edge cases galore that I donít know. I did not clean-up or check anything and I wrote 95% of it like 2 years ago; generally speaking, I cannot remember code I wrote last week.

    I may not explain much of any of it,

    As it stands, you will have to have a webserver. I am using plackup with https support. If you have your own host or something, you can definitely use that. Without supporting https this stuff wonít work unless you unblock the sources with your browser (a PITA and not a good idea).

    This code does a skosh of dynamic handling of the Chatterbox.

    Nodelet settings

    In your Free Nodelet Settings you will need to add several lines.

    <script src="//code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo= +" crossorigin="anonymous"></script> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.mi +n.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.2/highlig +ht.min.js"></script> <script src="//buzzword.org.uk/2014/pm/pm2.js"></script> <script src="//localhost:8282/pm/he.js"></script> <script src="//localhost:8282/pm/pm.2.0.js"></script> <script src="//localhost:8282/pm/pm.2.0.cb.js"></script> <link rel="stylesheet" href="//localhost:8282/pm/pm.2.0.css" type="tex +t/css" />

    The jQuery and Bootstrap are from, I think, reliable CDNs. he.js is a library for handling characters and HTML entities; hence ďhe.Ē The main formatting script, pm2.js, is from tobyinkís buzzword.org.uk. The next JS and CSS are mine and youíll have to serve them yourself from somewhere. Tobyís code needs Bootstrap. My code needs jQuery.

    he.js

    If you donít have it installed already via node or something, just take the he.js file to serve: https://github.com/mathiasbynens/he

    pm.2.0.js

    pm.2.0.cb.js

    Code to try to make the Chatterbox more dynamic. It has bugs, including an initial double display, that havenít bugged me enough to fix yet. If you use/edit it, please be careful not to put a bunch of load on the server with bad timers, etc.

    pm.2.0.css

    The only purpose here is to do a sort of anti-spinner. When you click I've checked all of these on the Recently Active Threads page, it blanks the page so you know something happened and shows it when the ajax has loaded it in the background. I probably should have just done it in JS but I thought Iíd be doing more CSS so started a fileÖ

    body { opacity: 0 !important; transition: opacity 0.5s; }

    If you donít have a webserver already, this is how I run mine on :8282; youíll need Plack::App::Directory. Donít ask me how to do your own certs. I do it less than annually and itís always a RTFM situation.

    plackup -p 8282 -MPlack::App::Directory -e \ 'Plack::App::Directory->new({root => q{/path/to/the/files}})->to_app +' \ --enable-ssl \ --ssl-key-file /path/to/certs/localhost.key \ --ssl-cert-file /path/to/certs/localhost.cert
filter-ports-commit-log.pl - Filter, highlight FreeBSD Ports one-line commit log messages
No replies — Read more | Post response
by parv
on Jul 10, 2021 at 06:42

    Description: Purpose is to remove inane (one-line) commit log messages of FreeBSD Ports Git repository, and highlights some others. It is not currently suitable to filter long form of commit messages.

Compile and possibly run cuda code on the GPU via Perl's Inline::C
1 direct reply — Read more / Contribute
by bliako
on Jul 02, 2021 at 04:48

    Here is my attempt to run Nvidia's cuda code on the GPU via Perl. The motivation is from question Perl GPGPU Modules by kcott (interesting problem, Ken!). The main tool is Inline::C which opens so many doors.

    Cuda is a programming language on top (or extending) C which deals with GPGPU. General-purpose computing on graphics processing units (GPGPU) tries to use graphics cards (GPU) and their highly parallel architecture to run tasks, like (large) matrix multiplication, which a CPU, because of its architecture, runs much slower and inefficiently. The GPU is designed for matrix multiplications and that's what it does frame after frame of what we see on our monitor without sweat. Matrix multiplication is the basis for a lot of numerical applications and can make social planning much easier.

    First the problems:

    • Nvidia provides its own compiler for cuda code: nvcc which compiles only cuda-specific code and the rest is delegated to the system compiler (e.g. gcc). So, as I understand it, both nvcc and gcc will be used to compile a cuda program which does have cuda extensions, i.e. it is not just "plain" C code.
    • Nvidia is very picky about the version of the system compiler. It usually only supports older compilers which must live in your system along with the system/current compiler. That's a bit of a kerfuffle. For example nvcc 11.4 supports up to gcc10, whereas my system compiler is at 11.1. My Linux system does not support installing other compilers via the package manager, or at least I did not find out how. Instead I resorted in building an older version from source with its own --prefix e.g. gcc84 and use that for each nvcc call using nvcc --compiler-bindir /usr/local/gcc84/bin/gcc84. Linking using nvcc requires the same treatment. See this for how to compile and install a second compiler in Linux with its own name-prefix-postfix.
    • nvcc does not take all the flags and parameters gcc takes. Instead, any flag to be passed on to the system compiler must be preceded by -Xcompiler
    • nvcc needs its input files to have the extension .cu

    Here is the general setup:

    Use Inline::C, which is a great and powerful module! thanks!, with specific compiler and linker by providing it (via use Inline C => Config => cc => '...', ld => '...') with two Perl scripts namely nvcc-compile.pl and nvcc-link.pl These will remove some incompatible compile/link flags which Inline::C and ExtUtils::MakeMaker use for compiling plain C code. They will also prefix others with -Xcompile ... to pass them on to the system compiler. The first script will also rename one of the temporary files produced in _Inline/build/ directory so that its extension is .cu and not .c. Then compiler and linker scripts proceed in running the actual nvcc command appropriate for compiling or linking. These scripts just worked for me but will probably need tweaking for other compilers and other flags. At least a general setup is in place.

    The two scripts to be provided to Inline::C as compiler and linker are given at the end. Edit: Save them at the same location as the demo script below without changing their names.

    Here is a basic Perl script running a cuda program on the GPU:

    #!/usr/bin/perl # by bliako @ PerlMonks.org # date: 01-Jul-2021 # see https://perlmonks.org/?node_id=11134582 # lame example for utilising GPGPU via Inline::C # TODO: extend to taking params and returning back results use strict; use warnings; use FindBin; use Inline C => Config => cc => $FindBin::Bin.'/nvcc-compile.pl', ld => $FindBin::Bin.'/nvcc-link.pl', ; use Inline C => <<'EOC'; // from https://developer.nvidia.com/blog/easy-introduction-cuda-c-and +-c/ #include <stdio.h> __global__ void saxpy(int n, float a, float *x, float *y) { int i = blockIdx.x*blockDim.x + threadIdx.x; if (i < n) y[i] = a*x[i] + y[i]; } int main() { int N = 1<<20; float *x, *y, *d_x, *d_y; x = (float*)malloc(N*sizeof(float)); y = (float*)malloc(N*sizeof(float)); cudaMalloc(&d_x, N*sizeof(float)); cudaMalloc(&d_y, N*sizeof(float)); for (int i = 0; i < N; i++) { x[i] = 1.0f; y[i] = 2.0f; } cudaMemcpy(d_x, x, N*sizeof(float), cudaMemcpyHostToDevice); cudaMemcpy(d_y, y, N*sizeof(float), cudaMemcpyHostToDevice); // Perform SAXPY on 1M elements saxpy<<<(N+255)/256, 256>>>(N, 2.0f, d_x, d_y); cudaMemcpy(y, d_y, N*sizeof(float), cudaMemcpyDeviceToHost); float maxError = 0.0f; for (int i = 0; i < N; i++) maxError = max(maxError, abs(y[i]-4.0f)); printf("Max error: %f\n", maxError); cudaFree(d_x); cudaFree(d_y); free(x); free(y); return 0; // << late edit! } EOC main;

    nvcc-compile.pl

    nvcc-link.pl

    At the moment, I have not implemented communicating parameters to and from the inlined cuda code. Feel free to extend.

    Suggestions: Inline::C can be modified in order to avoid my ugly hacks, or a new Inline::Cuda can be built.

    These are interesting times. This is a small step in making them fun-ner and lazy-er too. A big Thank You to the author of Inline::C and Nvidia.

    Tested on Linux with (older) gcc version 8.4, Nvidia's Cuda compilation tools version 11.4.48, Nvidia graphics driver 470.42.01, Perl version 5.32.1, Inline::C version 0.81

    Edits: main demo script added a return 0; at the end of main()

    bw, bliako

Extract/Print Firefox Bookmarks HTML File
2 direct replies — Read more / Contribute
by jmlynesjr
on Jun 25, 2021 at 19:06

    Here's a script to extract and print/save the URLs exported by the Firefox Export Bookmarks to HTML function.

    I know squat about HTML, but seem to have stumbled onto a good example.

    A flakey laptop is the mother of invention.

    #! /usr/bin/perl # bookmarks.pl - Script to extract and print the URLs created by the F +irefox # Export Bookmarks to HTML feature. # # James M. Lynes Jr. - KE4MIQ # Created: June 25, 2021 # Last Modified: 06/25/2021 - Initial version # Environment: Ubuntu 16.04 LTS # # Note: The raw HTML is very messy as it seems to include long strings # of encoded images. # Working code shamelessly stolen from the perldoc HTML::Element # example. use HTML::TreeBuilder; open(my $outfile, ">", 'bookmarks.txt') or die "Can't open bookmarks.t +xt: $!"; print $outfile "Firefox Bookmark URLs\n"; print $outfile "=====================\n"; my $tree = HTML::TreeBuilder->new(); $tree->parse_file('bookmarks.html'); for (@{ $tree->extract_links('a') }) { my($link, $element, $attr, $tag) = @$_; print "$link\n"; print $outfile "$link\n"; } $tree->delete;

    James

    There's never enough time to do it right, but always enough time to do it over...

3D printing with out slicers and safety nets
No replies — Read more | Post response
by cavac
on Jun 09, 2021 at 12:21

    As some of you might know, i'm running a simulated space agency for fun and non-profit.

    A couple of years ago i came across something called crushable aluminium honeycomb for things like one-time-use super lightweight shock absorbers. ESA also has some version of special aluminium foam for the same purpose. Those super rich engineering departments over at ESA and NASA really have all the coolest toys, though.

    I don't have the metal working tools to replicate that (or a furnace or blocks of aluminium, for that matter). But i do have a couple of 3D printers and i know Perl. That's pretty much the same thing, isn't it?

    Looking at the requirements of how a 3D printed crushable PLA structure could work, it was pretty clear from the start that using a modeling program like OpenSCAD and a slicer software wouldn't work. My plan is to print a hard structure filled with lots of very thin PLA strands that would break under load, therefore absorbing energy. The slicer would either print those strand too thick or would remove them entirely.

    The only option i could see that would generate the results i want was to generate the printer commands myself. After a lot of on-and-off tinkering, i still don't have a working crushable structure, but i decided to post my printer test code now, so you all have a chance to play around with it if you want.

    A word of warning! The code is printer specific (i'm using a modified Creality Ender 5 Pro), so you will have to adapt at least some settings. Most 3D printers are also very dumb and will try to do whatever you tell them to do - most times "no matter what the consequences are". If you tell your printer "move the head 10 meters to the left and then set the extruder temperature to the surface temperature of the sun" it will happily crash the head and then try to burn your house down. I've named my codebase "Project Arcturus", if you are a Stargate Atlantis fan, you'll know why ;-)

    This code will generate my default "test object". Let's dive into it.

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
Compiling and uploading a crontab to my Radioduino
2 direct replies — Read more / Contribute
by cavac
on May 28, 2021 at 04:15

    For background information: I'm working on my Radioduino, a souped up version of an Arduino Uno with lots of inbuild features like a real-time clock and external memory etc. It communicates via nRF24 radio with my nRF24 "modem", which in turn is accessible via Net::Clacks in my local network.

    One of the features is a scheduler, similar to a Linux/Unix crontab. This is stored in FRAM in binary form and basically injects uplink radio commands at specified times into the command sequencer.

    The structure of the crontab in the Radioduino is this:

    typedef struct { uint8_t mode; uint8_t hour; uint8_t minute; uint8_t second; uint16_t offset; uint8_t command; uint8_t datalength; uint8_t data[16]; } SCHEDULEENTRY;

    Of course, this is binary and a pain in the seating arrangement to edit by hand. So i made some perl tools to compile plain ASCII text files and upload them.

    I hope this post isn't too boring and helps inspire some ideas for your own projects.

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
Stylish Tk clock -- oneliner
2 direct replies — Read more / Contribute
by Discipulus
on May 12, 2021 at 08:28
    ..I'm sorry.. I couldn't resist :)

    perl -MTk -e "$w=tkinit;$w->optionAdd('*font','Courier 20 bold');$w->L +abel(-textvariable=>\$n,-background=>'lavender')->pack;$w->repeat(100 +,sub{$n=scalar localtime time});MainLoop"

    L*

    PS minimalistic version

    perl -MTk -e "$w=tkinit;$w->geometry('400x1');$w->repeat(100,sub{$w->configure(-title=>scalar localtime time)});MainLoop"

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
boilerplate - solution
1 direct reply — Read more / Contribute
by plvicente
on May 11, 2021 at 06:29

    Hello Perl Monks. I found a solution for the last posts and for my new boilerplate perl issue and solution. I am coding two html default pages.
    Every page has similarities but one can list and search, the other can login or be registered.

    So, I will post a small solution code that i used for my server.

    I hope that I can help here too. I am a learner as all here. This was a solution that I seek and found easily to my problem. Build a good website template boilerplate for my company. Thank you all.

Align given substring(s) in lines
3 direct replies — Read more / Contribute
by johnaj
on Apr 28, 2021 at 14:55

    I chose not to use strict for this one, and it was actually kind of nice for a simple script like this one. Especially the autovivification. Note that the script doesn't work too well if the alignment points you specify don't appear in the same order as you specify them. The script could also be optimized by getting rid of the separate first pass.

    #!/usr/bin/perl -w # align -- align given substrings in standard input lines use Getopt::Std; $Getopt::Std::STANDARD_HELP_VERSION = 1; getopts('a', \%opt); sub VERSION_MESSAGE {} sub HELP_MESSAGE { print <<OPT; usage: $0 [-s] [string ...] -a add an extra space before split You should put the strings in the order that they occur in each line. Note that only the last string is guaranteed to align. OPT } @splits = @ARGV; # alignment points @splits = (' #') if not @splits; # default (Perl comment) while (<STDIN>) { chomp; push @lines, $_; } for $split (@splits) { $max = 0; # Find max column for split string for (@lines) { if (/(.+?)(\Q$split\E)(.*)/) { $max = length $1 if length $1 > $max; $_ = [$1, "$2$3"]; } } # Add one extra space before split $max++ if $opt{a}; # Add spaces before split for (@lines) { $_ = sprintf("%-${max}s%s", $_->[0], $_->[1]) if ref; } } print "$_\n" for @lines;

    Here is an example of how to use the script from the UNIX shell:

    $ cat example my $string = 'some value'; # these my $int = 12; # are my $float = 1.2; # scalars $ cat example | ./align = \# my $string = 'some value'; # these my $int = 12; # are my $float = 1.2; # scalars

    I personally use it to great effect in vi, so that I can type !}align to align the comments in the next block of code.

Creating X BitMap (XBM) images with directional gradients
1 direct reply — Read more / Contribute
by kcott
on Apr 02, 2021 at 04:34

    G'day All,

    I'm continuing my project to create interactive maps for RPGs with Tk generally and, for the main part, Tk::Canvas. I wrote a bit about that in "Tk::Canvas createGroup() Undocumented"; this CUFP post has nothing to do with the issue in that SoPW post; there is some backgound information and (very early, now substantially matured) code which may be of interest. The test code there to create creeks is related to the current work creating paths.

    I had created the basic paths, put nicely curved bends in them, and so on. All of this looked good except for where the paths terminated upon entering a glade, meadow, or whatever: all I had at the ends was solid lines; what I wanted was for these to gradually peter out. The sections for this needed to be solid (opaque) where the main path ended and gradually fade to nothingness (transparent) as the terrain moved away from the path. In addition, this gradient needed to have direction to match the direction of the path where it terminated.

    I made one futile attempt to do this manually in Gimp: the result looked horrible. I decided to let Perl do it for me. Here's the result which I knocked up this afternoon.

    — Ken

Modifying Image EXIF
No replies — Read more | Post response
by johngg
on Mar 24, 2021 at 12:23

    I was on the point of posting this anyway but BernieC's question makes it quite timely to do so now.

    I recently dug an old DSLR camera out of a cupboard to take some pictures, just to give it an outing really as I have newer cameras. Unfortunately I didn't notice that the camera had lost its date settings and had gone back to its epoch of January 1st, 2010. Not only were the dates wrong but also the filenames as the month and day is included in those, 1 .. 9, A .. C for the month then day number in offsets 1 through 3. The camera is usually configured to take only RAW files but sometimes I save both RAW and JPEG files so I had to cater for both. Luckily I knew the dates the camera had been used so I could modify filenames and EXIF dates but I also wanted the timestamps to have a sane time so I added a routine to increment the time from a starting point a random number of seconds for each successive photo. Here's the script:-

    use strict; use warnings; use Time::Piece; use Image::ExifTool qw{ :Public }; use feature qw{ say }; my $baseDir = q{/Path/To/Images/}; my @dirsToCorrect = ( { dir => q{20201206_JimBirthday/}, dateCode => q{C06}, dateStr => q{2020:12:06 17:49:11}, }, { dir => q{20210224_Garden/}, dateCode => q{224}, dateStr => q{2021:02:24 11:17:23}, }, ); foreach my $rhDir ( @dirsToCorrect ) { my $imgDir = $baseDir . $rhDir->{ dir }; my $dateSeq = makeDateSeq( $rhDir->{ dateStr } ); opendir my $imgDH, $imgDir or die qq{opendir: $imgDir: $!\n}; my @rawFiles = grep m{\.ORF$}, readdir $imgDH; closedir $imgDH or die qq{closedir: $imgDir: $!\n}; foreach my $rawFile ( @rawFiles ) { say qq{Processing $rawFile ...}; my $origPath = $imgDir . $rawFile; my $newRawFile = $rawFile; substr $newRawFile, 1, 3, $rhDir->{ dateCode }; my $newPath = $imgDir . $newRawFile; my $correctedDate = $dateSeq->(); my $exifTool = Image::ExifTool->new(); $exifTool->SetNewValue( q{CreateDate}, $correctedDate ); $exifTool->SetNewValue( q{DateTimeOriginal}, $correctedDate ); $exifTool->SetNewValue( q{FileName} => $newRawFile, Protected +=> 1 ); writeNewExif( $exifTool, $origPath, $newPath ); ( my $possJPGfile = $rawFile ) =~ s{ORF$}{JPG}; my $possJPGpath = $imgDir . $possJPGfile; next unless -e $possJPGpath; say qq{ ... and associated $possJPGfile ...}; my $newJPGfile = $possJPGfile; substr $newJPGfile, 1, 3, $rhDir->{ dateCode }; my $newJPGpath = $imgDir . $newJPGfile; $exifTool->SetNewValue( q{FileName} => $newJPGfile, Protected +=> 1 ); writeNewExif( $exifTool, $possJPGpath, $newJPGpath ); } } sub makeDateSeq { my $dateStr = shift; my $dateVal = Time::Piece->strptime( $dateStr, q{%Y:%m:%d %H:%M:%S +} ); return sub { $dateVal += ( int rand 75 ) + 10; return $dateVal->strftime( q{%Y:%m:%d %H:%M:%S} ); }; } sub writeNewExif { my( $exifTool, $origPath, $newPath ) = @_; print q{ } x 10, qq{writing $newPath ... }; my $success = $exifTool->WriteInfo( $origPath, $newPath ); if ( ! $success ) { say q{FAILED - }, $exifTool->GetValue( q{Error} ); } elsif ( $success == 1 ) { say q{OK, wrote changes}; print q{ } x 10, qq{removing $origPath ... }; say unlink( $origPath ) ? q{OK} : qq{FAILED - $!}; } else { say q{FAILED, wrote unchanged}; print q{ } x 10, qq{removing $newPath ... }; say unlink( $newPath ) ? q{OK} : qq{FAILED - $!}; } }

    Here's another script that pulls the EXIF out of files supplied as arguments and Data::Dumper->Dumpxs()'s the results. The files from my cameras include an embedded thumbnail image which I exclude from the dump as it just messes up the output.

    use strict; use warnings; use Image::ExifTool qw{ :Public }; use Data::Dumper; my %exif; while ( my $file = shift ) { do { warn qq{$file does not exist\n}; next; } unless -e $file; $exif{ $file } = ImageInfo( $file ); delete $exif{ $file }->{ ThumbnailImage }; } print Data::Dumper ->new( [ \ %exif ], [ qw{ *exif } ] ) ->Sortkeys( 1 ) ->Indent( 1 ) ->Dumpxs();

    I hope this is useful.

    Update: Note that the Image::ExifTool documentation states that the WriteInfo() method will accept a single filename argument in which case it will overwrite the original file with the new EXIF information included. It does encourage the user to make sure to have backups!

    Cheers,

    JohnGG

Tk and GD to custom rotate, resize and crop jpg images
No replies — Read more | Post response
by Discipulus
on Mar 15, 2021 at 11:57
    Hello folks!

    Tk and GD again. Imagine to have a lot of pictures of the same subject, let say historical Kawasaki motorcycles, but where this subject is off center, sometimes bigger sometimes smaller, other times the picture is rotated and you want to have them with the subject of the same size, always horizontal and all pictures centered. Dreadful hours of photo editing or.. tk-jepg-custom-rotator! :)

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Add your CUFP
Title:
CUFP:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":


  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2021-07-28 10:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?