ImageMagick Preserve Exif Data - resize

I have a resizing function that does it's primary job right, but doesn't save
the exif data that comes with the original image file. Everything seems to be
correct until I call ->writeImage(); function, which seems to strip the exif
data of the image.
$resizeimage= new Imagick($image);
$exifDataArray = $resizeimage->getImageProperties("exif:*");
$resizeimage->thumbnailImage($width,$height);
$resizeimage->setImageCompression(imagick::COMPRESSION_JPEG);
$resizeimage->setImageCompressionQuality(90);
echo $resizeimage->setImageProperty('Exif:Make', 'BLABLABLA');
$resizeimage->writeImage();
$updated= new Imagick($image);
echo $updated->getImageProperty('Exif:Make');
Note that If I print_r($exifDataArray); it shows the exif data
To make a change I put 'Exif:Make', 'BLABLABLA' and see if the
new exif data is written on the image, and it is written correctly
but after I resizeimage->writeImage();
No more exif data is present on the image file.
Can anybody help? Is there any way to keep the exif data on the image?

It seems the error isn't there for the first time.
A workaround I use at the moment:
exiftool -overwrite_original_in_place -tagsFromFile $source_file $converted_file

You should not use the thumbnailImage image method if you want to preserve exif data. The following is from the documentation of ImageMagick (http://www.imagemagick.org/script/command-line-options.php#thumbnail):
-thumbnail geometry
This is similar to -resize, except it is optimized for speed and any image
profile, other than a color profile, is removed to reduce the thumbnail size.
You should use the method resizeImage instead (http://www.php.net/manual/en/imagick.resizeimage.php)

Related

How to properly use QSkyBoxEntity?

I looked everywhere, but there are not any guides or explanations of how to use QSkyBoxEntity.
I created Entity and filled it with transform (set translation and 3d scale). Also changed name and extension.
When I'm trying to run program it says
"Qt3D.Renderer.OpenGL.Backend: Unable to find suitable Texture Unit for "skyboxTexture""
I checked several times and tried different png files but no luck.
My image (I know it's fake transparency, but it shouldn't change anything, right?)
And here's part of a code:
Qt3DCore::QEntity *resultEntity = new Qt3DCore::QEntity;
Qt3DExtras::QSkyboxEntity *skyboxEntity = new Qt3DExtras::QSkyboxEntity(resultEntity);
skyboxEntity->setBaseName("skybox"); //I tried using path as well
skyboxEntity->setExtension("png");
Qt3DCore::QTransform *skyTransform = new Qt3DCore::QTransform(skyboxEntity);
skyTransform->setTranslation(QVector3D(0.0f,0.0f,0.0f));
skyTransform->setScale3D(QVector3D(0.1f,0.1f,0.1f));
skyboxEntity->addComponent(skyTransform);
Looks like it's not finding the skybox texture. Did you use an absolute path when you say "I tried using path as well"? The path you set is relative to the build path, i.e. it's not where your C++ file lies.
Alternatively, you could use a resources file and then load then image using
"qrc:/[prefix]/[filename without extension]"
You can also check out the Qt3D manual SkyBox test here:
https://github.com/qt/qt3d/tree/dev/tests/manual/skybox
It's important to properly name files in order for skybox to work and use resource file for storing.
I recommend .tga, but other formats should work as well.
You can read about it here:
https://doc.qt.io/qt-6/qml-qt3d-extras-skyboxentity.html
And here's example how it should look

Is it possible to rename png files by the time of creation, not after

I am using File[] imageFile = PdfUtilities.convertPdf2Png(new File("MYPATH")) command to generate png from pdf , which is giving file name as "workingimage01","workingimage02"...."workingimage0n" and so on, is it possible to change this name setting by the time png's are generated. Thanks in advance.
I am trying this command for 10 pdf parallel, so it is overlapping. thats why i need to know is there a way or i am asking out of the box question.
The name is hard coded in the source. You can create an overloaded method that takes another parameter for the working files' name.

new BitmapImage from Imagelist.images

Im trying to change the source of windows.media.imagesource
I store all my images in a windows.forms.imagelist
my code is: Source = New BitmapImage((MyImageList.Images(2)))
a system.uri is expected but I cannot find the conversion method
ok i dont know the rest of your code but i asume that for adding the images to the image list you first look for an uri, save the uri's in an Array and then call them from there.
Note:there is no method for getting an Uri from a Bitmap.

Why doesn't setImageInterlaceScheme() make a jpeg progressive?

I'm using php Gmagick to modify images. The following code works as expected except that the images are not progressive. Why? According to the GraphicsMagick docs it should. For reference, the input image is 666 x 1000.
$img = new Gmagick();
$img->setSize(900, 900)
->readImageBlob($image->getBytes())
->setImageInterlaceScheme(Gmagick::INTERLACE_PLANE)
->setImageResolution(96, 96)
->setImageFormat('jpeg')
->setCompressionQuality(70)
->resizeImage(900, 1351, Gmagick::FILTER_UNDEFINED, 1);
Note that
$img->getImageInterlaceScheme() === Gmagick::INTERLACE_PLANE
does return true after setting it.
Edit
I've tried both the INTERLACE_LINE and INTERLACE_PLANE constants. With neither seeming to have an effect on the output.
The original author created a bug on php.net (https://bugs.php.net/bug.php?id=66444), where the correct answer was eventually posted. You need to use the undocumented method:
->setInterlaceScheme(Gmagick::INTERLACE_LINE)
Instead of:
->setImageInterlaceScheme(Gmagick::INTERLACE_LINE)
This worked for me! For reference I am using PHP 5.4.20 with gmagick 1.1.7RC2 on top of GraphicsMagick 1.3.18.
The documentation you point to states:
Use Line to create an interlaced PNG or GIF or progressive JPEG image.
So, I think you should be setting the interlace to line.
->setImageInterlaceScheme(Gmagick::INTERLACE_LINE)
Note: I'm not sure if INTERLACE_LINE is an actual value. I assumed it was based on your code. Basically, try the line option.
Have you tried calling setImageInterlaceScheme before anything else? i cannot find the code, but maybe when you read the bits it already compose the image and then the interlacings takes no place.
$img
->setImageInterlaceScheme(Gmagick::INTERLACE_PLANE)
->readImageBlob($image->getBytes())
->setSize(900, 900)
->setImageResolution(96, 96)
->setImageFormat('jpeg')
->setCompressionQuality(70)
->resizeImage(900, 1351, Gmagick::FILTER_UNDEFINED, 1);
For sure the interlaceScheme has to be INTERLACE_PLANE, as you can read in the docs you already know http://www.graphicsmagick.org/GraphicsMagick.html#details-interlace
I've finally found the answer to this (using PHP IMagick) after struggling for weeks.
It turns out you have to set the image format to 'pjpeg' instead of just jpeg.
I have no idea why by by doing so my Images are correctly detect as progressive and render progressively in the browser.
I assume this will be the same for 'GMagick'
$im->setImageFormat('pjpeg')

Paperclip attachment file size

How do I fetch the file size of each style of a paperclip attachment?
#user.attachment_file_size doesn't seem to work
#user.attachment(:style).size
gives a number not related to the actual file size
I didn't find either how to get the file size for a given style, other than the original one.
As seen in the paperclip source code, #user.attachment.size returns the size of the file as originally assigned. There is no way to get it for a specific style...
A solution would be:
open(#user.attachment(:style)).size
But not efficient at all.
To do it well, you should probably add some "custom size" fields in your attachment table that you would fill once the attachment is saved for each style...
User find by ID(for example)
User has :photo
#user.last.photo_file_size
You can get a string like "WIDTHxHEIGHT" inside styles hash, for the giving object's style, using Paperclip::Style#geometry:
string = #user.attachment.styles[:size].geometry
Than you can split the string to have either height or width:
width = string.split("x")[0]
height = string.split("x")[1]
It seems it is possible actually
Just have to cath the temporary files for each style and applying size method.
let's say you have two styles large and small for your attachment called image and you have created two extra fields in your model large_size and small_size to save those values.
Just add the below bit of code to your model:
before_create :assign_sizes
private
def assign_sizes
self.large_size = image.queued_for_write[:large].size.to_i
self.small_size = image.queued_for_write[:small].size.to_i
end
The fields large_size and small_size will be popuated with each style file size. And this will be done before the files are sent to S3 for example. So there is no extra querying the files headers from S3.