Perl module Image::Imlib2 trouble saving gifs - perl

I'm using the perl module Image:Imlib2 to resize photos. Here is the code:
#create thumbnail
my $old = Image::Imlib2->load("$upload_dir/$name");
my $new = $old->create_scaled_image(80, 80);
$new->save("$upload_dir/$thumbnail_name");
This code works fine when I am saving a jpg or png file, but whenever I save a gif, I get an internal server error. Here is the error I get in my apache log file:
Image::Imlib2 save error: Unknown error at /path/to/script/script.pl
Any Ideas?
Thanks!

I don't think Imlib2 supports writing GIF files at all. From a rather old mailing list posting:
I discovered that Imlib2 has absolutely NO support for writing out gif files.
Furthermore, if you look at the source, you'll see a couple files of interest:
imlib2-1.4.5/src/modules/loaders/loader_png.c
imlib2-1.4.5/src/modules/loaders/loader_gif.c
Inside loader_png.c you'll find this:
char
load(ImlibImage * im, ImlibProgressFunction progress,
char progress_granularity, char immediate_load)
{
/*...*/
}
char
save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
{
/*...*/
}
and inside loader_gif.c, you'll find:
char
load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
char immediate_load)
{
/* ... */
}
but no save implementation. So it looks like Imlib2 can read GIFs but can't write them and that's where your trouble lies.
I'd recommend that you switch to GraphicsMagick and Graphics::Magick. GraphicsMagick is a fork of ImageMagick that is faster and has fewer bugs, this is what Flickr uses internally so it should be good enough for you. GraphicsMagick unfortunately uses the somewhat strange ImageMagick API but you can hide the ugly details behind a wrapper without too much difficulty.
Alternatively, save all your thumbnails as JPEGs or PNGs.

Related

Is there a way to get possible characters for a image (containing single character) in tesseract?

I tried searching around in the internet, github issues and such, but was unable to find if it's possible to get the result with different possible character alternatives while using tesseract.
for example while running tesseract -l jpn --psm 10 input.png - on this image I get the output 白, but if possible I'd like to also see the other possibilities, and if possible with their confidence coefficients.
I found that it's specially useful while trying to recognize a single character as the tesseract --psm 10 will give wrong but close results for complex kanji.
Like was being recognized as 側. So, I was thinking if I could like get the 5 most probable or sth like that from the command line, then it could be great. And if it's not possible through the command line I'm also willing to see a direct programming approach using the API.
EDIT:
tesseract -l jpn --psm 10 iu.png - command on results in 雨 result. On doing this on the code given in the answer I can see that the confidence is 93.68% and shows only one result. If I run the same in this image instead , I'll get 言 (99.46%) which means it is giving a sensible result, but it's only giving me a single result ignoring others. I hypothesized that it does so because the confidence is high because if I run the same command on , I get 遊 but when I run the code, I get
遊 (71.77%)
遮 (67.41%)
遭 (66.76%)
避 (65.36%)
遷 (65.00%)
選 (64.70%)
透 (64.55%)
進 (64.52%)
適 (63.95%)
週 (63.22%)
Hence, I assume it's giving single result in previous images because it is confident.
Furthermore doing tesseract -l jpn_vert screenshot.png - in this image gives the output 言わない, which is correct, which means even when it gave me 雨 result on the cropped character in the same image, there was 言 match there but with lower coefficient but it came up when it was doing the dictionary match in the whole word (which removed 雨 as a possibility). That's why while trying to identify a single character, I want to get the output with all those matches (a fixed number or a threshold decided by myself).
The code I have is almost identical to the one given in the example I have only added whitelist characters (around 2000+ kanji). Had to remove api->SetVariable("tessedit_char_whitelist", ...) line because SO thought it was spam.
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
#include <tesseract/publictypes.h>
int main(int argc, char *argv[]){
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
// Initialize tesseract-ocr with Japanese, without specifying tessdata path
if (api->Init(NULL, "jpn")) {
fprintf(stderr, "Could not initialize tesseract.\n");
exit(1);
}
// Open input image with leptonica library
Pix *image = pixRead(argv[1]);
api->SetImage(image);
api->SetVariable("save_blob_choices", "T");
api->SetPageSegMode(tesseract::PSM_SINGLE_CHAR);
api->Recognize(NULL);
tesseract::ResultIterator* ri = api->GetIterator();
tesseract::PageIteratorLevel level = tesseract::RIL_SYMBOL;
if(ri != 0) {
do {
const char* symbol = ri->GetUTF8Text(level);
float conf = ri->Confidence(level);
if(symbol != 0) {
tesseract::ChoiceIterator ci(*ri);
do {
const char* choice = ci.GetUTF8Text();
printf("%s (%.2f%%)\n", choice, ci.Confidence());
} while(ci.Next());
}
delete[] symbol;
} while((ri->Next(level)));
}
// Destroy used object and release memory
api->End();
pixDestroy(&image);
return 0;
}
IMHO you will need to use tesseract API https://github.com/tesseract-ocr/tessdoc/blob/master/APIExample.md#example-of-iterator-over-the-classifier-choices-for-a-single-symbol

Libfuzzer target for on-disk parsing

I'm currently integrating libFuzzer in a project which parses files on the hard drive. I have some prior experience with AFL, where a command line like this one was used:
afl-fuzz -m500 -i input/ -o output/ -t100 -- program_to_fuzz ##
...where ## was a path to the generated input.
Looking at libFuzzer however, I see that the fuzz targets look like this:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
DoSomethingInterestingWithMyAPI(Data, Size);
return 0; // Non-zero return values are reserved for future use.
}
I understand that the input isn't provided in the form of a file, but as a buffer in-memory instead. The problem is that the program I'm trying to fuzz works with files and obtains its data through fread() calls. At no point in time is the whole input supposed to be loaded in memory (where, in the general case, it might not even fit); so there's not much I can do with a const uint8_t*.
Writing the buffer back to the hard drive to get back a file seems extremely inefficient. Is there a way around this?
You can do as in this example from google security team.
The buf_to_file defined here takes your buffer and returns a char* pathname you can then pass to you target:
(from https://github.com/google/security-research-pocs/blob/master/autofuzz/fuzz_utils.h#L27 )
// Write the data provided in buf to a new temporary file. This function is
// meant to be called by LLVMFuzzerTestOneInput() for fuzz targets that only
// take file names (and not data) as input.
//
// Return the path of the newly created file or NULL on error. The caller should
// eventually free the returned buffer (see delete_file).
extern "C" char *buf_to_file(const uint8_t *buf, size_t size);
Be sure to free the ressource with the delete_file function.
You could use LD_PRELOAD and override fread.

three.js toDataURL PNG is black

I'm trying to grab a screenshot with renderer.domElement.toDataURL("image/png"), and save it to a file.
The image is the right size, but it's black.
I have preserveDrawingBuffer turned on.
I think I'm decoding and saving the file correctly, because when I hexdump it I can see the correct initial characters for the PNG format, as well as the IHDR and IDAT chunk headers. However the closing IEND is missing.
Any known issues here? Hints? Windows 7/Firefox up to date if it matters.
Thanks... (Sorry if this is dumb, I'm very new to three.js)
I had somewhat similar problems with Windows 7/Firefox. PNG Data URL's would be randomly truncated or something, much shorter than a successful PNG export. Trying to set that data url as image src resulted in "Image corrupt" exception or something in FF. As little sense it makse, setting a small window.setTimeout (10ms) between rendering and getting the data URL helped in my case. Maybe Firefox needs a rest from the JS engine before it refreshes some canvas internal state or something.. weird.
I switched to JPG format (smaller files => truncation less of an issue?) and still saw it not working, then I tried this tip which I found here
If you want to save data that is derived from a Javascript
canvas.toDataURL() function, you have to convert blanks into plusses.
If you do not do that, the decoded data is corrupted:
<?php
$encodedData = str_replace(' ','+',$encodedData);
$decodedData = base64_decode($encodedData);
?>
This worked. Thanks, Mekal.
This tip seems to apply to JPGs only. I saw PNGs decoding correctly without the + replacement, and corruptly with it. I can use JPGs so my personal problem is solved. However I never saw a PNG that wasn't black even when decoded correctly and not truncated.
Kind of a lousy situation either way, I feel like. What is up with the +'s?
A black texture is a sign that you did not indicate the texture needs to be updated.
Also, you do not need to use canvas.toDataURL(). You can pass in the canvas reference to the THREE.Texture object.
var canvas = document.getElementById('#myCanvas');
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
// Now render the scene

JPEG encoder super slow, how to Optimize it?

I'm building an App with actionscript 3.0 in my Flash builder. This is a followup question this question.
I need to upload the bytearray to my server, but the function i use to convert the bitmapdata to a ByteArray is super slow, so slow it freezes up my mobile device. My code is as follows:
var jpgenc:JPEGEncoder = new JPEGEncoder(50);
trace('encode');
//encode the bitmapdata object and keep the encoded ByteArray
var imgByteArray:ByteArray = jpgenc.encode(bitmap);
temp2 = File.applicationStorageDirectory.resolvePath("snapshot.jpg");
var fs:FileStream = new FileStream();
trace('fs');
try{
//open file in write mode
fs.open(temp2,FileMode.WRITE);
//write bytes from the byte array
fs.writeBytes(imgByteArray);
//close the file
fs.close();
}catch(e:Error){
Is there a different way to convert it to a byteArray? Is there a better way?
Try to use blooddy library: http://www.blooddy.by . But i didn't test it on mobile devices. Comment if you will have success.
Use BitmapData.encode(), it's faster by orders of magnitude on mobile http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#encode%28%29
You should try to find a JPEG encoder that is capable of encoding asynchronously. That way the app can still be used while the image is being compressed. I haven't tried any of the libraries, but this one looks promising:
http://segfaultlabs.com/devlogs/alchemy-asynchronous-jpeg-encoding-2
It uses Alchemy, which should make it faster than the JPEGEncoder from as3corelib (which I guess is the one you're using at the moment.)
A native JPEG encoder is ideal, asynchronous would be good, but possibly still slow (just not blocking). Another option:
var pixels:ByteArray = bitmapData.getPixels(bitmapData.rect);
pixels.compress();
I'm not sure of native performance, and performance definitely depends on what kind of images you have.
The answer from Ilya was what did it for me. I downloaded the library and there is an example of how to use it inside. I have been working on getting the CameraUI in flashbuilder to take a picture, encode / compress it, then send it over via a web service to my server (the data was sent as a compressed byte array). I did this:
by.blooddy.crypto.image.JPEGEncoder.encode( bmp, 30 );
Where bmp is my bitmap data. The encode took under 3 seconds and was easily able to fit into my flow of control synchronously. I tried async methods but they ultimately took a really long time and were difficult to track for things like when a user moved from cell service to wifi or from tower to tower while an upload was going on.
Comment here if you need more details.

Using .png files instead of using .ico files in windows programs

hi I have a collection of nice .png files....
meanwhile, I'm developing a win-based software and need some .ico files as icons for toolbar buttons and ....
Is there any way to use .png file as an icon ? or what?
Thank you
As a workaround you can use IrfanView to convert your *.png file to *.ico file (or any other image to ico) & use it.
http://www.irfanview.com/main_download_engl.htm
You can simply convert the images to ico files online Ico Convert.
If you are using .NET this is not a real problem for you, because afaik PNG support is already build in. You are probably talking about native C/C++ development with GDI/win32?
To my knowledge you will not accomplish this by simply using GDI. There are a couple of options where you can set ONE color as transparent then load a simple BMP/JPEG and do some BITMAP tricks however using ICO/GIF will be far easier for this.
What you are probably looking for is a working GDI+ example which will use a PNG with alpha channel? This is just an excerpt and I left out the whole mess loading external functions from a DLL part, but maybe this will help you:
static GpImage *background = NULL;
GDIPLOADIMAGEFROMSTREAM GdipLoadImageFromStream;
GDIPLUSSTARTUP GdiplusStartup;
GDIPPLUSSHUTDOWN GdiplusShutdown;
GDIPCREATEFROMHDC GdipCreateFromHDC;
GDIPDELETEGRAPHICS GdipDeleteGraphics;
GDIPDRAWIMAGEI GdipDrawImageI;
GDIPDRAWIMAGERECTI GdipDrawImageRectI;
GDIPLUS_STARTUP_INPUT GdiplusStartupInput;
void LoadPNG(GpImage **image, int resource, HMODULE hInstance)
{
HRSRC resrc;
LPSTREAM lpstr;
HGLOBAL hPng;
LPVOID fByte;
GpImage *img = NULL;
resrc = FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(resource), TEXT("PNG"));
hPng = LoadResource(GetModuleHandle(NULL), resrc);
fByte = LockResource(hPng);
lpstr = SHCreateMemStream(fByte, 200000);
GdipLoadImageFromStream(lpstr, &img);
*image = img;
}
void CreateBack(HWND hWnd)
{
HDC memDC = NULL;
HDC hdc = NULL;
RECT rect;
DeleteObject(curBack);
GetClientRect(hWnd, &rect);
hdc = GetDC(hWnd);
memDC = CreateCompatibleDC(hdc);
curBack = CreateCompatibleBitmap(hdc, rect.right, 44);
SelectObject(memDC, curBack);
/* gdiplus - background*/ {
int e = 0;
GpGraphics *g;
GdipCreateFromHDC(memDC, &g);
GdipDrawImageRectI(g, background, e, 0, 971, 44);
GdipDeleteGraphics(g);
}
DeleteObject(memDC);
ReleaseDC(hWnd, hdc);
}
Just a quick note: This GDI+ stuff is really CPU/memory intensive for a couple of reasons. Although fun I did abandoned this approach in favor of gdi and simple BMPs.
If you're loading the images from a resource file, then no, you can't use PNGs, you have to use ICOs. Fortunately, there are a number of tools that can convert PNGs into ICOs, including ImageMagick (great for automation), and MSPaint as a lowest common denominator.
If you're loading image files at runtime, then you can load any type of image format you want (e.g. use libpng for loading PNGs), but you still have to convert them to icons internally before you can do interesting things with them, such as setting them as a window's icon. Once you've decoded the image data, it's not terribly difficult to convert it to the proper format, but it's not trivial, it just involves a lot of data mangling and strange structs and function calls from the Win32 API.