How can you save an Image (microedition.lcdui.Image) object into storage?
I have this Image object:
Image outImg; //Contains image data
I tried the code below to save it to storage but without success:
int[] rgb = new int[240*320];
outImg.getRGB(rgb, 0, 240, 0, 0, 240, 320);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
dout.writeInt(240);
dout.writeInt(320);
for (int i = 0; i < rgb.length; i++) {
dout.writeInt(rgb[i]);
}
bytes = bout.toByteArray();
FileConnection fcOut = (FileConnection) Connector.open("file:///root1/img.png", Connector.READ_WRITE);
if (!fcOut.exists()) {
fcOut.create();
}
DataOutputStream out = fcOut.openDataOutputStream();
out.write(bytes);
I searched for a solution but didn't find anything useful. How can I achieve this?
Alternatively, is there a way I can convert an Image object to a byte array? So I can use DataOutputStream to write the byte array to memory.
Related
I'm trying to upload files to an Azure fileshare using the library Azure.Storage.Files.Shares.
If I don't chunk the file (by making a single UploadRange call) it works fine, but for files over 4Mb I haven't been able to get the chunking working. The file is the same size when downloaded, but won't open in a viewer.
I can't set smaller HttpRanges on a large file as I get a 'request body is too large' error, so I'm splitting the filestream into multiple mini streams and uploading the entire HttpRange of each of these
ShareClient share = new ShareClient(Common.Settings.AppSettings.AzureStorageConnectionString, ShareName());
ShareDirectoryClient directory = share.GetDirectoryClient(directoryName);
ShareFileClient file = directory.GetFileClient(fileKey);
using(FileStream stream = fileInfo.OpenRead())
{
file.Create(stream.Length);
//file.UploadRange(new HttpRange(0, stream.Length), stream);
int blockSize = 128 * 1024;
BinaryReader reader = new BinaryReader(stream);
while(true)
{
byte[] buffer = reader.ReadBytes(blockSize);
if (buffer.Length == 0)
break;
MemoryStream uploadChunk = new MemoryStream();
uploadChunk.Write(buffer, 0, buffer.Length);
uploadChunk.Position = 0;
file.UploadRange(new HttpRange(0, uploadChunk.Length), uploadChunk);
}
reader.Close();
}
The code above uploads without error, but when downloading the image from Azure it is corrupt.
Does anyone have any ideas? Thanks for any help you can provide.
cheers
Steve
I was able to reproduce the issue. Basically the problem is with the following line of code:
new HttpRange(0, uploadChunk.Length)
Essentially you're always setting the content at the same range and that's why the file is getting corrupted.
Please try the code below. It should work. What I did here is defined the HTTP range offset and moving it constantly with number of bytes already written to the file.
using (FileStream stream = fileInfo.OpenRead())
{
file.Create(stream.Length);
//file.UploadRange(new HttpRange(0, stream.Length), stream);
int blockSize = 1 * 1024;
long offset = 0;//Define http range offset
BinaryReader reader = new BinaryReader(stream);
while (true)
{
byte[] buffer = reader.ReadBytes(blockSize);
if (buffer.Length == 0)
break;
MemoryStream uploadChunk = new MemoryStream();
uploadChunk.Write(buffer, 0, buffer.Length);
uploadChunk.Position = 0;
HttpRange httpRange = new HttpRange(offset, buffer.Length);
var resp = file.UploadRange(httpRange, uploadChunk);
offset += buffer.Length;//Shift the offset by number of bytes already written
}
reader.Close();
}
I am creating a project in which I want to compress image so that it can be uploaded easily on windows azure and later can be retrieved easily from windows azure to my application.So can you please help me with how can I do that. I am using BitmapImage right now . Follwoing is the code which I am using to upload image to azure
void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(e.ChosenPhoto);
WriteableBitmap wb = new WriteableBitmap(bitmap);
using (MemoryStream stream = new MemoryStream())
{
wb.SaveJpeg(stream, wb.PixelWidth, wb.PixelHeight, 0, 0);
AzureStorage storage = new AzureStorage();
storage.Account = **azure account**;
storage.BlobEndPoint = **azure end point**;
storage.Key = **azure key**;
string fileName = uid;
bool error = false;
if (!error)
{
storage.PutBlob("workerimages", fileName, imageBytes, error);
}
else
{
MessageBox.Show("Error uploading the new image.");
}
}
}
}
Be care using the WriteableBitmap as you may run out of memory if resizing a lot of images. If you only have a few, then pass the size you want saved to the SaveJpeg method. Also make sure you use a value higher than 0 for the quality (last param of SaveJpeg)
var width = wb.PixelWidth/4;
var height = wb.PixelHeight/4;
using (MemoryStream stream = new MemoryStream())
{
wb.SaveJpeg(stream, width, height, 0, 100);
...
...
}
You can also use the JpegRenderer from the Nokia Imaging SDK to resize an image.
var width = wb.PixelWidth/4;
var height = wb.PixelHeight/4;
using (var imageProvider = new StreamImageSource(e.ChosenPhoto))
{
IFilterEffect effect = new FilterEffect(imageProvider);
// Get the resize dimensions
Windows.Foundation.Size desiredSize = new Windows.Foundation.Size(width, height);
using (var renderer = new JpegRenderer(effect))
{
renderer.OutputOption = OutputOption.PreserveAspectRatio;
// set the new size of the image
renderer.Size = desiredSize;
IBuffer buffer = await renderer.RenderAsync();
return buffer;
}
}
Working on one windows application (.Net 4.0) which will accept font file name as input and will return images for each glyph in font. Tried all possible Google stuff but not getting all glyph s images. And if getting images that also have some wrong out put. Please suggest me the ways to do this... Currently had following work out...
private void generateBitmaps(string strFontpath)
{
////Generate font object
GlyphTypeface font = new GlyphTypeface(new Uri(strFontpath));
int fontSize = 22;
int intGlyphcount = 0;
//Collect geometry of all glyphs
var Glyphs = from glyphIndex in font.CharacterToGlyphMap.Values
select font.GetGlyphOutline(glyphIndex, fontSize, 1d);
// now create the visual we'll draw them to
DrawingVisual viz = new DrawingVisual();
System.Drawing.Size cellSize = new System.Drawing.Size(fontSize, Convert.ToInt32(fontSize * font.Height));
int bitWidth = (int)Math.Ceiling(Convert.ToDecimal(cellSize.Width*10));
int bitHeight = (int)Math.Ceiling(Convert.ToDecimal(cellSize.Height * 10));
//using (DrawingContext dc = viz.RenderOpen())
{
foreach (var g in Glyphs)
{
if (intGlyphcount > font.GlyphCount)
break;
//if (g.IsEmpty())
// continue; // don't draw the blank ones
DrawingContext dc = viz.RenderOpen();
dc.PushTransform(new TranslateTransform());
System.Windows.Media.Pen glyphPen = new System.Windows.Media.Pen(System.Windows.Media.Brushes.Black, 1);
dc.DrawGeometry(System.Windows.Media.Brushes.Red, glyphPen, g);
//GeometryDrawing glyphDrawing = new GeometryDrawing(System.Windows.Media.Brushes.White, glyphPen, g);
//DrawingImage geometryImage = new DrawingImage(glyphDrawing);
//dc.DrawImage(geometryImage, new Rect(0, 0, 150, 150));
dc.Close();
//geometryImage.Freeze();
//dc.Pop(); // get rid of the transform
RenderTargetBitmap bmp = new RenderTargetBitmap(
200, 200,
96, 96,
PixelFormats.Pbgra32);
bmp.Render(viz);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
using (FileStream file = new FileStream(#"GlyphList\Glyph" + intGlyphcount++ + ".png", FileMode.Create))
encoder.Save(file);
//dc.Pop();
}
}
MessageBox.Show("Done");
}
If You got glyph in font as image use external dll
This dll is available in url
http://www.gnostice.com/XtremeFontEngine_dot_NET.asp
I'm running a multi thread image compressing process. The original file is 1280x
960 high resolution PNG file, about 1800KB. I need compress to <70KB JPEG file. When I process few vehicles, the process runs fine. when I process over 20 vehicles, I start to get out of memory error. Here is the code.
private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
public static void SaveAsJpg(string inFilePath = null, string outputFileName = null, long compression = 70, long quality = 70)
{
System.Drawing.Image orgimage = System.Drawing.Image.FromFile(inFilePath);
var imgIn = new Bitmap(orgimage);
var imgOut = new Bitmap(imgIn.Width, imgIn.Height);
Graphics g = Graphics.FromImage(imgOut);
g.Clear(Color.White);
g.DrawImage(imgIn, 0, 0, imgIn.Width, imgIn.Height);
EncoderParameters encoding = new EncoderParameters(2);
encoding.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, compression);
encoding.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg");
imgOut.Save(outputFileName, myImageCodecInfo, encoding);
}
Thanks in advance for any suggestion.
I think you need to dispose the graphic objects before leaving the method.
g.Dispose();
orgiImage.Dispose();
imgIn.Dispose();
imgOut.Dispose();
Disposing System.drawing objects
Currently i am giving hard-coded path for saving the file, but need to open Dialog box to ask user's to get location to save the file on drive.
My Client Code is:
//Service1Client client = new Service1Client();
client.Open();
string s = client.GetData(5);
stream1 = client.GetFileStream("20101102.zip");
string filePath=#"c:\Test\";
outstream = File.Open(filePath, FileMode.Create, FileAccess.Write);
//CopyStream(stream1, outstream);
const int bufferLen = 10000000;
byte[] buffer = new byte[bufferLen];
int count = 0;
int bytecount = 0;
while ((count = stream1.Read(buffer, 0, bufferLen)) > 0)
{
outstream.Write(buffer, 0, count);
bytecount += count;
}
}
Please help me how can i achieve this functionality by some sample code.
Thanks in advance
What is the client? What is the problem with SaveFileDialog in WinForms or similar in other types of applications?