I'm writing a simple J2ME game that uses PNG images with 8-bit alpha channel. Problem: not all hardware supports full alpha transparency rendering. However, since my game is pretty static in nature (at the beginning, "sprites" are layed out onto background image, based on current screen size, and that's about it), I thought it would be possible to prerender those transparent images directly onto background during game initialization and use that later in game. I can't prerender them in Photoshop as their positions are not known in advance.
But, it seems there is no way to read the original alpha channel on devices that do not support semi-transparency as it gets resampled during PNG loading. Is there some library that can help with that? Or is it a good idea to store alpha channels separately (e.g. as separate 8-bit PNG images) and manually apply them?
Thanks!
PNG Images also have transparency support if you want to create transparent image then you have read RGB data along with alpha channels and process alpha
Image transPNG=Image.createImage("/trans.png"); //load the tranparent image
int rgbData[];
transPNG.getRGB(rgbData, 0,transPNG.getWidth(), 0, 0,transPNG.getWidth(), transPNG.getHeight());
Image tranparentImage=Image.createRGBImage(rgbData, width, height, true); //process alpha
transPNG=null;
Above code shows how to create the transparent image and use.
I cant promise this will help, but you can try this way of reading the alpha channel using standard methods from Java util.
BufferedImage image = ImageIO.read(new File(name));
int[] alpha = new int[1]; //containg alpha-value for one pixel.
image.getAlphaRaster().getPixel(x, y, alpha);
System.out.println(alpha[0]); //gives the alpha value for x,y
Related
The below snippet darkens the entire image but I wish to darken all the parts except the background. How would one go about doing this? You will notice the png below has no background so I am not sure why this doesn't work.
I am guessing it is something to do with how the image is loaded into memory from the file and alpha channels etc.
SKImage image = SKImage.FromBitmap(resourceBitmap);
var skImageFilter = SKImageFilter.CreateColorFilter(SKColorFilter.CreateBlendMode(AppColors.DarkGreyColor.ToSKColor(),
SKBlendMode.Darken));
image = image.ApplyImageFilter(
skImageFilter, new SKRectI(0,0, image.Width,image.Height), new SKRectI(0, 0, image.Width, image.Height), out SKRectI subSet, out SKPoint point);
This is possible by wrapping the SKImageFilter, taken from this other stack overflow question:
SKImageFilter.CreateBlendMode(SKBlendMode.DstIn,
SKImageFilter.CreateColorFilter(SKColorFilter.CreateBlendMode(AppColors.DarkGreyColor.ToSKColor(), SKBlendMode.Darken)));
I'm making a game were you can set the background image yourself.
The selected image is resized to make it fit the purpose, and then i want to load the picture into pygame.
I've something like:
image = Image.open('file')
image.thumbnail(size, Image.ANTIALIAS)
And now I want to load image into pygame.
of course I can use:
image.save(outfile, "JPEG")
background = pygame.image.load('outfile')
Is there a nice way without having to save the image to my hard drive?
Or is it possible that pygame resizes the image?
You can use pygame.transform.scale() to resize an image:
pygame.transform.scale()
resize to new resolution
scale(Surface, (width, height), DestSurface = None) -> Surface
Resizes the Surface to a new resolution. This is a fast scale operation that does not sample the results.
An optional destination surface can be used, rather than have it create a new one. This is quicker if you want to repeatedly scale something. However the destination must be the same size as the (width, height) passed in. Also the destination surface must be the same format.
So you don't have to use PIL.
I am doing a Drawing App. I have saved the color fill image as bitmapImage in collection. Again I open the saved image for drawing. If i fill the color of image, the color filling not clear. I have used ExtensionJpg for save Image.
WriteableBitmap pBitmap;
pBitmap = new WriteableBitmap(imgDraw, null); // imgDraw is jpg image bitmapImage binded to source.
BitmapImage img1 = new BitmapImage();
MemoryStream ms = new MemoryStream();
pBitmap.SaveJpeg(ms, (int)pBitmap.PixelWidth, (int)pBitmap.PixelHeight, 0, 100);
img1.SetSource(ms);
In this case again i have binded the this bitmap Image to imgDraw Source. But to saw the image is very clear.
When i fill colors to imgDraw is not applied correctly.
Thanks
When you encode a bitmap as a Jpeg file you can lose data. that is part of the design of lossy compression algorithms such as Jpeg.
Even worse, using a lossy compression can introduce (hardly visible) artifacts. So by saving the image as Jpeg you are probably adding pixels to the large, clear area. These pixels cause the fill to fail.
You have three options:
Do not use a lossy algorithm by switching to e.g. PNG
Change the quality of the compression
Change the fill algorithm to be more tolerant of nearly-the-same-color pixels.
I noticed that you set the quality to 100 but this question makes me doubt the quality of the jpeg implementation of the method you might be using. You could switch to PNG to see if that helps.
Is there any way of creating transparent mutable images in JavaME (CLDC 1.1, MIDP 2.0) ?
public static Image createImage(int width, int height)
Creates mutable image but not transparent one (at least not on Nokia phones!)
Any other Image.create* creates immutable images and I don't know any way of creating mutable image from immutable one.
I need this to create "prerendering" functionality. Join several images into one to make rendering faster (I could join this images once and then draw them all in one call. It saves time and memory since I don't need to keep original images).
Maybe someone can think of any other way of accomplishing the same effect?
You can use the Image.getRGB() to get the image data as an int array and process the alpha component and then draw that int[] to the Graphics using Graphics.drawRGB(). This might not work on phones that dont support alpha transparency
Unfotunately no. MIDP does not support transparent mutable Images. You can stil use Image for pre-rendering some content, but you have to work around not having transparent pixels.
I have valid HBITMAP handle of ARGB type. How to draw it using GDI+?
I've tried method:
graphics.DrawImage(Bitmap::FromHBITMAP(m_hBitmap, NULL), 0, 0);
But it doesn't use alpha channel.
I've got working sample:
Get info using bitmap handle: image size, bits
BITMAP bmpInfo;
::GetObject(m_hBitmap, sizeof(BITMAP), &bmpInfo);
int cxBitmap = bmpInfo.bmWidth;
int cyBitmap = bmpInfo.bmHeight;
void* bits = bmpInfo.bmBits;
Create & draw new GDI+ bitmap using bits with pixel format PixelFormat32bppARGB
Gdiplus::Graphics graphics(dcMemory);
Gdiplus::Bitmap bitmap(cxBitmap, cyBitmap, cxBitmap*4, PixelFormat32bppARGB, (BYTE*)bits);
graphics.DrawImage(&bitmap, 0, 0);
I had similar issues getting my transparent channel to work. In my case, I knew what the background color should be used for the transparent area (it was solid). I used the Bitmap.GetHBITMAP(..) method and passed in the background color to be used for the transparent area. This was a much easier solution that other attempts I was trying using LockBits and re-creating the Bitmap with PixelFormat32bppARGB, as well as cloning. In my case, the Bitmap was ignoring the alpha channel since it was created from Bitmap.FromStream.
I also had some very strange problems with the background area of my image being changed slightly. For example, instead of pure white, it was off white like 0xfff7f7. This was the case whether I was using JPG (with blended colors) or with PNG and transparent colors.
See my question and solution at
GDI+ DrawImage of a JPG with white background is not white
Ah... but .Net doesn't use HBITMAP and GDI+ is a C++ library atop the basic Windows GDI, so I'm assuming you're using non-.Net C++.
GDI+ has a Bitmap class, which has a FromHBITMAP() method.
Once you have the GDI+ Bitmap instance, you can use it with the GDI+ library.
Of course, if you can write your program in C# using .Net it will be a lot easier.