The color of video is wrong when made from UIImage of the PNG files - iphone

I am taking a UIImage from Png file and feed it to the videoWriter.
avAdaptor appendPixelBuffer:pixelBuffer
When the end result video comes out, it seems to lacking the one color, missing the yellow color or something.
I take alook of the function that made the pixelbuffer out of the UIImage
CVPixelBufferCreateWithBytes(NULL,
myWidth,
myHeight,
kCVPixelFormatType_32BGRA,
(void*)CFDataGetBytePtr(image),
CGImageGetBytesPerRow(cgImage),
NULL,
0,
NULL,
&pixelBuffer);
I also try the kCVPixelFormatType_32AGRB and others, it didn't help.
any thoughts?

Please verify if your PNG image is with or without transparency element. If your PNG image doesn't contain transparency then it's 24-bit and not 32-bit per pixel.
Also, have you tried kCVPixelFormatType_32RGBA ?

Maybe the image sizes do not fit together.
Your input image should have the same width and height like the video output. If "myWidth" or "myHeight" is different (i.e. different aspect ratio) to the size of the image, one byte may be lost at the end of the line, which could lead to color shifting. kCVPixelFormatType_32BGRA seems to be the preferred (fastest) pixel format, so this should be okay.
There is no yellow color in RGB colorspace. This means yellow is only the >red< and >green< components. It seems that >blue< is missing.
I assume you are using a CFDataRef (maybe NSData) for the image. If it is an NSData object you can print the bytes to the debug console using
NSLog(#"data: %#", image);
This will print a hex dump to the console. Here you can see if you have alpha and what kind of byte order your png is alike. If your image has alpha, every fourth byte should be the same number.

Related

How can I increase the bit depth of an image while keeping it transparent?

I am using UIGraphicsBeginImageContext(canvasRect.size) to export images, but because UIGraphicsBeginImageContext uses only 8-bit context, the exported image has the original image's The color representation was dropped, resulting in a blurry appearance.
Therefore, we changed the code to UIGraphicsBeginImageContextWithOptions(canvasRect.size, true, 1.0).
The original image was successfully exported as a clean image with no loss of color representation, but transparency is no longer represented because opaque was set to true.
Please let me know if you know how to increase the bit rate while keeping the transparency of the image.
Please let me know if there is any other method other than UIGraphicsBeginImageContextWithOptions that can be used to export an image while preserving the color representation of the image.

With ffmpeg's example extract_mvs.c, I am getting black and white images from color rtsp camera

I am using the extract_mvs.c from ffmpeg:
https://ffmpeg.org/doxygen/2.5/extract__mvs_8c_source.html
I added opencv to imwrite the image.
cv::Mat img(frame->height,frame->width,CV_8UC1,frame->data[0]);
imwrite( "pic.jpg", img );
That works because the image in the frame is in grayscale. The camera is a color camera however, and I dont know why I am getting grayscale. If I cange the above to CV_8UC3, I get segmentation fault.
I tried to save the image with ppm_save function and I still get a black and white frame when there should be a color frame. Any ideas?
Thanks,
Chris
Just read about graphics file formats and such. JPG requires BGR24 format. The raw frame buffer format YUV420P needs to be converted to BGR24 using swscale. Then the output frames height and width needs to be manually set before calling :
cv::Mat img(out_frame->height,out_frame->width,CV_8UC3,out_frame->data[0]);
imwrite( "pic.jpg", img );
Likewise,PPM file format requires RGB24 and the raw format needs to be converted to this before saving the ppm file.
Thanks,
Chris

Transparency with JPEGs

JPEGs are smaller in size than PNGs. So, I thought that if I can make a specific region in a JPEG-file transparent, with some code, maybe I can save some bytes.
So does anyone know how to achieve this with for example PHP or JavaScript?
No. You can't do this. JPGs do not support alpha channels and have no capacity to designate certain colors as transparent either (GIF-style).
There's several issues with this, all of them have to do with that JPEG is a lossy compression format. The JPEG format is optimized for natural images and sharp edges will get blurred. If you intend that a specific pixel should have the value #d67fff there's no guarantee that after color conversion, FDCT, quantization, IDCT and color conversion, the pixel still will have that value. There's also a strong possibility that that pixel value will occur in areas that you don't want.
No. JPEG does not support transparency and is not likely to do so any time
soon. http://www.faqs.org/faqs/jpeg-faq/part1/section-12.html
You cannot do that, the client renders the image and doesn't know that you want it to treat that color as transparent (plus various compression methods on jpeg wouldn't work well with transparencies anyway).
I believe you can go with an 8-bit custom-pallet png, should save you a lot of space. Otherwise 24-bit PNG is your only high color option.
You can convert your image to SVG containing a color information as JPEG and an alpha channel as grayscale mask. Here is a tool I wrote to do it https://github.com/igrmk/transpeg

Scaling the image -- Quality check

Does scaling the image using: image=[UIImage imageWithCGImage:[image CGImage] scale:2.0 orientation:UIImageOrientationUp]; reduces the image quality?
If you mean something like compression artefacts then no, cause those are added when it comes to saving to disc in a specific format like JPG.
There is also a yes, because you double the dimensions of the image which will interpolate the pixels that never have been there, this will always look blurry starting at a certain point.

Writing a masked image to disk as a PNG file

Basically I'm downloading images off of a webserver and then caching them to the disk, but before I do so I want to mask them.
I'm using the masking code everyone seems to point at which can be found here:
http://iosdevelopertips.com/cocoa/how-to-mask-an-image.html
What happens though, is that the image displays fine, but the version that gets written to the disk with
UIImage *img = [self maskImage:[UIImage imageWithData:data] withMask:self.imageMask];
[UIImagePNGRepresentation(img) writeToFile:cachePath atomically:NO];
has it's alpha channel inverted when compared to the one displayed later on (using the same UIImage instance here).
Any ideas? I do need the cached version to be masked, otherwise displaying the images in a table view get's awfully slow if I have to mask them every time.
Edit: So yeah, UIImagePNGRepresentation(img) seems to invert the alpha channel, doesn't have anything to do with the code that writes to disk, which is rather obvious but I checked anyway.
How about drawing into a new image, and then save that?
UIGraphicsBeginImageContext(img.size);
[img drawAtPoint:CGPointZero];
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[UIImagePNGRepresentation(newImg) writeToFile:cachePath atomically:NO];
(untested)
See the description in CGImageCreateWithMask in CGImage Reference:
The resulting image depends on whether the mask parameter is an image mask or an image. If the mask parameter is an image mask, then the source samples of the image mask act as an inverse alpha value. That is, if the value of a source sample in the image mask is S, then the corresponding region in image is blended with the destination using an alpha value of (1-S). For example, if S is 1, then the region is not painted, while if S is 0, the region is fully painted.
If the mask parameter is an image, then it serves as an alpha mask for blending the image onto the destination. The source samples of mask' act as an alpha value. If the value of the source sample in mask is S, then the corresponding region in image is blended with the destination with an alpha of S. For example, if S is 0, then the region is not painted, while if S is 1, the region is fully painted.
It seems for some reason the image mask is treated as a mask image to mask with while saving. According to:
UIImagePNGRepresentation and masked images
http://lists.apple.com/archives/quartz-dev/2010/Sep/msg00038.html
to correctly save with UIImagePNGRepresentation, there are several choices:
Use inverse version of the image mask.
Use "mask image" instead of "image mask".
Render to a bitmap context and then save it, like epatel mentioned.