Reassembling a fragmented image - image

I have an image that has been broken in to parts, 64 rows by 64 columns. Each image is 256x256px. The images are all PNG. They are named "Image--.png" for example "Image-3-57". The rows and columns numbering start from 0 rather than 1.
How can I assemble this back in to one image? Ideally using BASH and tools (I'm a sysadmin) though PHP would be acceptable as well.

Well, it is not very complicated, if you want to use PHP. What you need is just a few image gunctions - imagecreate and imagecopy. If your PNG is semi transparent, you will also need imagefilledrectangle to create a transparent background.
In code below, I rely on fact, that all chunks are same size - so the pixel size must be able to be divided by the number of chunks.
<?php
$width = 256*64; //height of the big image, pixels
$height = 256*64;
$chunks_X = 64; //Number of chunks
$chunks_Y = 64; //Same for Y
$chuk_size_X = $width/$chunks_X; //Compute size of one chunk, will be needed in copying
$chuk_size_Y = $height/$chunks_Y;
$big = imagecreate($width, $height); //Create the big one
for($y=0; $y<$chunks_Y; $y++) {
for($x=0; $x<chunks_X; $x++) {
$chunk = imagecreatefrompng("Image-$x-$y.png");
imagecopy($big, $chunk,
$x*$chuk_size_X, //position where to place little image
$y*$chuk_size_Y,
0, //where to copy from on little image
0,
$chuk_size_X, //size of the copyed area - whole little image here
$chuk_size_Y,
);
imagedestroy($chunk); //Don't forget to clear memory
}
}
?>
This is just a draft. I'm not sure about all theese xs and ys as well as ather details. It is late and I'm tired.

Related

Making a long image without resizing

I need to put many images together side by side but without changing the height or width of any of them. That is to say, it will just be one image of a constant height but very long width as the image are sitting horizontally.
I've been using Python and the PIL library but what I've tried so far is producing an image that makes all the images smaller to concatenate into one long image.
Image.MAX_IMAGE_PIXELS = 100000000 # For PIL Image error when handling very large images
imgs = [ Image.open(i) for i in list_of_images ]
widths, heights = zip(*(i.size for i in imgs))
total_width = sum(widths)
max_height = max(heights)
new_im = Image.new('RGB', (total_width, max_height))
# Place first image
new_im.paste(imgs[0],(0,0))
# Iteratively append images in list horizontally
hoffset=0
for i in range(1,len(imgs),1):
hoffset=imgs[i-1].size[0]+hoffset # update offset**
new_im.paste(imgs[i],(hoffset,0))
new_im.save('row.jpg')
The result I'm getting now is one image made up of concatenated images in a horizontal row. This is what I want, except the images are being made smaller and smaller in the concatenation process. I want the end result to not make the images smaller and instead produce an image made of the input images with their original size. So the output image will just have to have a very long width.
It seems you have a bug while updating the offsets.
You should replace your iteration block with:
imgs = [Image.open(i) for i in list_of_images]
widths, heights = zip(*(i.size for i in imgs))
new_img = Image.new('RGB', (sum(widths), max(heights)))
h_offset = 0
for i, img in enumerate(imgs):
new_img.paste(img, (h_offset, 0))
h_offset += img.size[0]

read pixels from image and randomly show single pixels in browser with PHP

I have an image that is saved in a database. I need a script that can read the RGB + x and y value of each pixel of this image.
This is needed because I want to be able to show random pixels of this image in a browser. With random I mean, random positions. The number of pixels is selected with a form. When the form is used, a number of pixels of the image will be visible in the browser and this new image will be saved. The next time the form is used, the new image with a few pixels visible, will be displayed in the browser. And so on.... each time the form is used, the image will get more and more visible.
I did some testing with the PHP GD library, but not been able to extract the RGB as well as the position of each pixel. For outputting an array of RGBA vallues, I used this how to count number of pixels in image (php). But as you see, this is just the beginning.
$img = "images/test.png";
$imgHand = imagecreatefrompng("$img");
$imgSize = GetImageSize($img);
$imgWidth = $imgSize[0];
$imgHeight = $imgSize[1];
// Define a new array to store the info
$pxlCorArr= array();
for ($l = 0; $l < $imgHeight; $l++) {
// Start a new "row" in the array for each row of the image.
$pxlCorArr[$l] = array();
for ($c = 0; $c < $imgWidth; $c++) {
$pxlCor = ImageColorAt($imgHand,$c,$l);
// Put each pixel's info in the array
$pxlCorArr[$l][$c] = ImageColorsForIndex($imgHand, $pxlCor);
}
}
do you want a partial image to be shown and then full image ? or random part of it ?
take a look at this ,
https://github.com/ogres/Image2HTML
it will convert an image to html table , you could edit it so only random part of image will be shown

Codeigniter - Re-sizing multiple images works, but wrong sizes?

I'm trying to resize a fullsize image poster into three smaller variants of the file. I first save the fullsize poster, then i use it's path to create the smaller ones. The problem is that the sizes are incorrect. I have a $conf array containing general config info for all images, and then i have a $conf array for each image with specific changes (eg. size). I clear the lib before every new init.
// Config for all images
$conf['source_image'] = $file_path;
$conf['quality'] = 80;
$conf['maintain_ratio'] = true;
$conf['master_dim'] = 'auto';
// Small
$conf['new_image'] = 'img/movie_images/posters_small/' . $file_name;
$conf['height'] = 75;
//$conf['width'] = 55;
$this->image_lib->initialize($conf);
$this->image_lib->resize();
$this->image_lib->clear();
//unset($conf['width']);
// Medium
$conf['new_image'] = 'img/movie_images/posters_medium/' . $file_name;
$conf['height'] = 200;
$this->image_lib->initialize($conf);
$this->image_lib->resize();
$this->image_lib->clear();
// Big
$conf['new_image'] = 'img/movie_images/posters_big/' . $file_name;
$conf['height'] = 300;
$this->image_lib->initialize($conf);
$this->image_lib->resize();
$this->image_lib->clear();
See any errors in the code? I tried outputting errors as someone advised in another question here, but that didn't show anything either. I don't understand how it works really. If i set "master_dim" to auto, the first (the small) image get's the right height, but the default width (which is really really wide). If i set master_dim to "width", the small image stays the same (really wide, but correct height). If i set master_dim to "height" they all get the correct height, but the small one still is super wide.
Any ideas?
As you can see in the code i tried playing around with the width of the small image to get it's correct size, but didn't get it to work.
After setting master_dim to height, and also setting the width of the small image manually, it works as i want it to.
You can download the image library from http://thephpcode.com/blog/codeigniter/gradient-image-library-for-codeigniter to convert the image to fit in to a correct width and size.

Magento resize() image quality: dirty white background

I have a client who is seriously unhappy with the way their product thumbnails are rendering on Magento.
The dodgy appearance is noticeable on two accounts:
there is a dirty white background which has very light grey horizontal lines
and secondly there is ever so slight color loss (loses contrast and saturation).
I have removed ALL compression, set ALL quality to 100%, flushed image cache, experimented, broken, and fixed it all dozens of times, and nothing seems to work.
This version of Magento is ver. 1.4.2.0
Is anyone out here experiencing the same problems, and if so have you managed to fix it?
The problem has to do with the php function imagecopyresampled in the resize function inside lib/Varien/Image/Adapter/Gd2.php, there are some rounding issues that occur to make a smoothly resized image.
My solution is to simply change any very light grey pixels in the image to pure white after the image has been resized. To do so first copy lib/Varien/Image/Adapter/Gd2.php to app/code/local/Varien/Image/Adapter/Gd2.php
Next find the following code inside the resize function (around line 312)
// resample source image and copy it into new frame
imagecopyresampled(
$newImage,
$this->_imageHandler,
$dstX, $dstY,
$srcX, $srcY,
$dstWidth, $dstHeight,
$this->_imageSrcWidth, $this->_imageSrcHeight
);
Then add the following code underneath:
// Clean noise on white background images
if ($isTrueColor) {
$colorWhite = imagecolorallocate($newImage,255,255,255);
$processHeight = $dstHeight+$dstY;
$processWidth = $dstWidth+$dstX;
//Travel y axis
for($y=$dstY; $y<($processHeight); ++$y){
// Travel x axis
for($x=$dstX; $x<($processWidth); ++$x){
// Change pixel color
$colorat=imagecolorat($newImage, $x, $y);
$r = ($colorat >> 16) & 0xFF;
$g = ($colorat >> 8) & 0xFF;
$b = $colorat & 0xFF;
if(($r==253 && $g == 253 && $b ==253) || ($r==254 && $g == 254 && $b ==254)) {
imagesetpixel($newImage, $x, $y, $colorWhite);
}
}
}
}
Flush the images cache from the Cache management in Magento, and you should have nicer images for the new displays. Few things to note when implementing this, there is a small performance hit the first time you generate the images again, and images with shadows may have sharper edges as the very light greys have been removed.
try following example
echo Mage::helper('catalog/image')->init($product, 'small_image')->resize(180, 210)->setQuality(50);
You can put your own Gd2.php file in local (app/code/local/Varien/Image/Adapter/Gd2.php) and hard-wire the quality to 100%.
Quality is working for me so I have not done that.
You can also put an image convolution in there to sharpen your images, in that way you get the blur of a resize compensated for with a sharpen, e.g. put the following just inside the end of the 'resize' function:
$sharpenMatrix = array(array(-1,-1,-1),array(-1,24,-1),array(-1,-1,-1));
$divisor = 16;
$offset = 0;
imageconvolution($newImage, $sharpenMatrix, $divisor, $offset);
I had problems with images quality on one of projects. But the problem was not on back-end, but on the front-end. Images had bad quality because images width and height given in the CSS was not the same as the image file had.
quick grep shows that you are able to set this on product_image object
app/code/core/Mage/Catalog/Helper/Image.php:105: * Set image quality, values in percentage from 0 to 100
app/code/core/Mage/Catalog/Helper/Image.php:107: * #param int $quality
app/code/core/Mage/Catalog/Helper/Image.php:110: public function setQuality($quality)
app/code/core/Mage/Catalog/Helper/Image.php:112: $this->_getModel()->setQuality($quality);
app/code/core/Mage/Catalog/Model/Product/Image.php:38: protected $_quality = 90;
app/code/core/Mage/Catalog/Model/Product/Image.php:88: * Set image quality, values in percentage from 0 to 100
app/code/core/Mage/Catalog/Model/Product/Image.php:90: * #param int $quality
app/code/core/Mage/Catalog/Model/Product/Image.php:93: public function setQuality($quality)
app/code/core/Mage/Catalog/Model/Product/Image.php:95: $this->_quality = $quality;
app/code/core/Mage/Catalog/Model/Product/Image.php:100: * Get image quality
app/code/core/Mage/Catalog/Model/Product/Image.php:106: return $this->_quality;
app/code/core/Mage/Catalog/Model/Product/Image.php:331: 'quality' . $this->_quality
app/code/core/Mage/Catalog/Model/Product/Image.php:387: $this->_processor->quality($this->_quality);
I had the same issue with some of my images, later i realized that those images with lower resolution were getting distorted, try using an image more than 1100 X 1100 and it should work just fine !
Upload the images as PNG's. They may not be as small as JPG, but it allowed us to avoid some image quality issues created by Magento's resizing functionality.

Prevent GDI+ PNG Encoder from adding Gamma information to a 1-bit PNG

I wonder if its possible to instruct the Imaging PNG Encoder not to add any gamma and chroma informations to a 1-bit PNG.
I am creating a 2 color palette for the image
ColorPalette* pal = (ColorPalette*)CoTaskMemAlloc(sizeof(ColorPalette) + 2 * sizeof(ARGB));
pal->Count = 2;
pal->Flags = 0;
pal->Entries[0] = MAKEARGB(0,0,0,0);
pal->Entries[1] = MAKEARGB(0,255,255,255);
if (FAILED(res = sink->SetPalette(pal))) {
return res;
}
CoTaskMemFree(pal);
and then just
BitmapData bmData;
bmData.Height = bm.bmHeight;
bmData.Width = bm.bmWidth;
bmData.Scan0 = bm.bmBits;
bmData.PixelFormat = PixelFormat1bppIndexed;
UINT bitsPerLine = imageInfo.Width * bm.bmBitsPixel;
UINT bitAlignment = sizeof(LONG) * 8;
UINT bitStride = bitAlignment * (bitsPerLine / bitAlignment); // The image buffer is always padded to LONG boundaries
if ((bitsPerLine % bitAlignment) != 0) bitStride += bitAlignment; // Add a bit more for the leftover values
bmData.Stride = bitStride / 8;
if (FAILED(res = sink->PushPixelData(&rect, &bmData, TRUE))) {
return res;
}
The resulting PNG image is way to large and contains the following useless headers:
sRGB,gAMA,cHRM
I was actually only expecting PLTE not sRGB. How do I have to setup the encoder to skip gamma and chroma calculations?
I'm also interested to know if it's possible. I use gdi+ in a c++ program to generate png's for a website and the png's have different colors than the css although I put in the exact same values. By removing the sRGB stuff, that could solve the gamma problem in most browsers.
I hope there is a solution for this!
I have resolved this by implementing the FreeImage library (http://freeimage.sourceforge.net/).
I create the bitmap with GDI+, I lock its pixeldata, create a freeimage bitmap, lock it too and copy the pixels.
Then I make freeimage save it to a PNG and voila... correct gamma information, good in every browser.
It's a little bit more overhead (although I have a feeling that FreeImage saves the images much faster than GDI+, making the overal process even faster). But of course, you will need an extra library with dll with your project.

Resources