I'm trying to use the type JpegBitmapEncoderin the name space System.Windows.Media.Imaging, but i can't seem to use it. The namespace itself is available and i can use it but for some reason the JpegBitmapEncoder is not there... How can i use it?
Perhaps you can use the extension methods on WritableBitmap to load and save a jpeg instead.
Extensions Methods - LoadJpeg, SaveJpeg
If you want to get a byte array from the image, use a MemoryStream and its ToArray to get the data.
MemoryStream stream = new MemoryStream();
image.SaveJpeg(stream, width, height, 0, 80);
stream.Position = 0;
byte[] buffer = stream.ToArray();
Related
I'm trying to add a PNG image to an existing pdf, but the transparency is converted to black color.
PdfReader reader = new PdfReader(pdfPath);
File f = new File(pdfPath);
String result = f.getParent() + File.separator + UUID.randomUUID().toString() + ".pdf";
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(result));
Image image = Image.getInstance(ImageIO.read(new File(imagePath)), null);
PdfImage stream = new PdfImage(image, null, null);
PdfIndirectObject ref = stamper.getWriter().addToBody(stream);
image.setDirectReference(ref.getIndirectReference());
image.setAbsolutePosition(30, 300);
PdfContentByte canvas = stamper.getOverContent(1);
canvas.addImage(image);
stamper.close();
reader.close();
How can I keep transparency?
First this: I am violating the policy at iText Software by answering this question. You are using an old version of iText, and the policy dictates that voluntary support on iText 5 or earlier has stopped. You should either use iText 7, or you should get a support contract if you still want support for an old iText version.
However, I am curious. I want to know where you found this clunky code (or why you decided to write this code):
Image image = Image.getInstance(ImageIO.read(new File(imagePath)), null);
PdfImage stream = new PdfImage(image, null, null);
PdfIndirectObject ref = stamper.getWriter().addToBody(stream);
image.setDirectReference(ref.getIndirectReference());
image.setAbsolutePosition(30, 300);
PdfContentByte canvas = stamper.getOverContent(1);
canvas.addImage(image);
You don't need ImageIO and you don't need to create a PdfImage, nor do you need to add that image to the body of a PDF file. The code you are using is code specialists would use for a very particular purpose. If you know that particular purpose, please explain.
If adding an image at an absolute position is all you want to do (that's a general purpose, not a particular purpose), your code should be as simple as this:
Image image = Image.getInstance(imagePath);
image.setAbsolutePosition(30, 300);
PdfContentByte canvas = stamper.getOverContent(1);
canvas.addImage(image);
In this case, you don't have to worry about the image mask; iText will take care of that for you.
Please also explain why you're using an outdated version of iText instead of iText 7. If you want your application to be future-proof, you should upgrade to iText 7 now (to avoid wasting time later).
I've got code along the lines of the following which generates a new image out of some existing images.
from PIL import Image as pyImage
def create_compound_image(back_image_path, fore_image_path, fore_x_position):
back_image_size = get_image_size(back_image_path)
fore_image_size = get_image_size(fore_image_path)
new_image_width = (fore_image_size[0] / 2) + back_image_size[0]
new_image_height = fore_image_size[1] + back_image_size[1]
new_image = create_new_image_canvas(new_image_width, new_image_height)
back_image = pyImage.open(back_image_path)
fore_image = pyImage.open(fore_image_path)
new_image.paste(back_image, (0, 0), mask = None)
new_image.paste(fore_image, (fore_x_position, back_image_size[1]), mask = None)
return new_image
Later in the code, I've got something like this:
from kivy.uix.image import Image
img = Image(source = create_compound_image(...))
If I do the above, I get the message that Image.source only accepts string/unicode.
If I create a StringIO.StringIO() object from the new image, and try to use that as the source, the error message is the same as above. If I use the output of the StringIO object's getvalue() method as the source, the message is that the source must be encoded string without NULL bytes, not str.
What is the proper way to use the output of the create_compound_image() function as the source when creating a kivy Image object?
It seems you want to just combine two images into one, you can actually just create a texture using Texture.create and blit the data to a particular pos using Texture.blit_buffer .
from kivy.core.image import Image
from kivy.graphics import Texture
bkimg = Image(bk_img_path)
frimg = Image(fr_img_path)
new_size = ((frimg.texture.size[0]/2) + bkimg.texture.size[0],
frimg.texture.size[1] + bkimg.texture.size[1])
tex = Texture.create(size=new_size)
tex.blit_buffer(pbuffer=bkimg.texture.pixels, pos=(0, 0), size=bkimg.texture.size)
tex.blit_buffer(pbuffer=frimg.texture.pixels, pos=(fore_x_position, bkimg.texture.size[1]), size=frimg.texture.size)
Now you can use this texture anywhere directly like::
from kivy.uix.image import Image
image = Image()
image.texture = tex
source is a StringProperty and is expecting a path to file. That's why you got errors when you tried to pass PIL.Image object, StringIO object or string representation of image. It's not what framework wants. As for getting image from StringIO, it was discussed before here:
https://groups.google.com/forum/#!topic/kivy-users/l-3FJ2mA3qI
https://github.com/kivy/kivy/issues/684
You can also try much simpler, quick and dirty method - just save your image as a tmp file and read it normal way.
I need to decode both bitmap and meta data from PNG input stream using [PNGJ] (http://code.google.com/p/pngj/) library. The problem is that decoding meta data will advance the stream and then I cannot use
bitmap = BitmapFactory.decodeStream().
Creating Bitmap on my own is OK but if I need to, say, scale bitmap with interpolation I'd rather use BitmapFactory. To use it I have to create a copy of InputStream every time I have to use PNGJ for getting meta data and BitmapFactory for getting a bitmap. It will be nice to return meta data AND Bitmap from a single PNGJ call (at least for most common ARGB_8888 format).
In a nutshell, I have to copy the stream to be used by Java libraries which looks like a waste. Returning a bitmap will be one solution.
// register an auxilary chunk name
PngChunk.factoryRegister(ThumbNailProvider.chunkID, chunkPROP.class);
// reader for the stream
PngReader pngr = new PngReader(inStream, "debug label PNG reader");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PngWriter pngw = new PngWriter(outputStream, pngr.imgInfo);
// copy pre-data chunks
pngw.copyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE);
// copy image data
for (int row = 0; row < pngr.imgInfo.rows; row++) {
ImageLine l1 = pngr.readRow(row);
pngw.writeRow(l1, row);
}
// copy after-data chunks
pngw.copyChunksLast(pngr, ChunkCopyBehaviour.COPY_ALL);
pngr.end(); // close inStream but not its copy
pngw.end(); // close out stream
// save a copy of the stream for Java Libraries;
data.inputStream = new ByteArrayInputStream(outputStream.toByteArray());
// read the chunk
ChunksList chunkList = pngr.getChunksList();
PngChunk chunk = chunkList.getById1(L2ThumbNailProvider.chunkID);
if (chunk != null) {
...
}
This is the problem of having two independent streams consumers, say Class1.parse(inputStream), Class2.decode(inputStream) and we want them to consume the same single stream; it has no simple elegant solutions (eg), if we have no control on how the consumers eat the stream.
Simple solutions, but not very elegant -and probably impractical- are: close and reopen the stream (unfeasible if we are reading from a network stream), buffer the full stream content in memory, or to a temporary file.
In your concrete case, the alternatives I can think of are:
1) Let PNGJ consume and decode the data and create the Bitmap yourself, filling the pixels it with setPixels(). This, among other inconveniences, would require you to do the proper color conversions.
2) Use PngReader as a InputFilterStream, so that it only parses the metadata and pass the full stream to the consumer. Currently, this is not possible, withouth tweaking on the PNGJ code. I will give it a look, and if a implement this feature I'll post it here.
I've got a windows 8 program that uses an image picker and downloads the selected image on the server.
The server provides an API which needs the image to be converted in base64string. And an image must be less than 7Mb.
I'm using the code below:
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
// Application now has read/write access to the picked file
bitmap = new BitmapImage();
byte[] buf;
using (var stream = await file.OpenStreamForReadAsync())
{
buf = ReadToEnd(stream);
}
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
base64String = Convert.ToBase64String(buf);
bitmap.SetSource(stream);
}
}
And the bitmap goes to the server.
But there is a problem: the bitmap size is much more bigger than jpg's size, for example. And none of small jpgs go to the server, because their bitmap version is larger than 7 Mb.
Can I convert an image to base64string without converting it to a bitmap?
In this code, you read the image (encoded in jpeg) and convert it to a base 64 string.
You can not reduce the size of the base 64 without reducing the size of the image.
To do so, you can use a BitmapEncoder/Decoder and resize the image to a smaller size.
Regards
I'd like to create programmatically a random X height and Y width bitmap file.
The content, for me, is irrelevant. It could be all white, empty. What is important is the dimension.
How to do it using Windows API?
You wish to create a Bitmap File using the windows API? There is no specific helper for this. a BMP file however is very simple:
Write out a BITMAPFILEHEADER struct.
Write out a BITMAPINFO struct.
Write out an array of bytes, enough to hold the format and dimensions described in the BITMAPINFO struct.
The MSDN has an Article with sample code demonstrating how.
I suppose you have Microsoft .NET 2.0 Framework installed. (1.1 is also usable).
Using Notepad, create test.cs file with this code:
namespace test
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 3)
new System.Drawing.Bitmap(System.Convert.ToInt32(args[0]), System.Convert.ToInt32(args[1]))
.Save(args[2] + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
else
System.Console.WriteLine("Usage: test.exe 100 200 filename");
}
}
}
Then create test.cmd file with this code:
#echo off
%windir%\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe test.cs
Execute test.cmd
Execute text.exe
In .Net you can just new up a Bitmap object:
Image myImage = new Bitmap(width, height);
GDI+ includes commands to load/save BMP images in C++. This sample code shows how to load and save images: Converting a BMP Image to a PNG Image. The Bitmap class also has a ctor that takes a width, a height and a pixel format to create empty images.
If you really insist on making an image with windows API,you should use Gdi32.dll
In C# just call
Import dll file into your assembly, so you can use external methods in
DllImport["Gdi32.dll"]
HBITMAP CreateCompatibleBitmap(
HDC hdc,
int nWidth,
int nHeight
);
Then call Bitmap class from this Bitmap like
Bitmap bmp = Bitmap.FromHbitmap( nameOfBitmap );
bmp.Save("C:\NewImage.jpg");
There is an example in msdn page here