i have a byte Object and want to turn it into a texture.
basically the same thing like in the Template (EX9.Texture), but instead of a fill function a byte object.
at the moment, i have this workaround:
byte[]() tileObj = (byte[]())command.ExecuteScalar(); // what i get from a sqlite DB
if (tileObj == null)
{
//here i want to put an "empty" texture in my texture
}
else
{
// here i managed to put the byte[]() into a BitmapImage
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = new MemoryStream[byte[](](https://vvvv.org/documentation/byte[]()tileObj);
image.EndInit();
// then convert the BitmapImage into a Bitmap and put it into the textures metadata
info.TileBM = BitmapImage2Bitmap(image) ;
}
a function that converts BitmapImage into Bitmap
private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
{
using(MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapImage));
enc.Save(outStream);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream);
// return bitmap; <-- leads to problems, stream is closed/closing ...
return new Bitmap(bitmap);
}
}
suppose the byte array contains only pixel after pixel in RGBA format (no header), something like this should work:
// somewhere in evaluate
info.Width = from sqlite; // width in pixel
info.Height = from sqlite; // height in pixel
info.Data = from sqlite; // byte[]()
...
// in update texture
var dataRectangle = texture.Lock(0, LockFlags.None);
try
{
// compute pitch of source and destination (might differ, as size of textures are often a power of two, depends on hardware)
var srcPitch = info.Data.Length / info.Height;
var dstPitch = dataRectangle.Pitch;
var dstDataStream = dataRectangle.Data;
if (srcPitch == dstPitch)
{
// pitch is the same, we can do the copy in one pass
dstDataStream.WriteRange(info.Data);
}
else
{
// pitch differs, we need to copy line by line
for (int i = 0; i < height; i++)
{
var srcOffset = srcPitch * i;
var dstOffset = dstPitch * i;
dstDataStream.Position = dstOffset;
dstDataStream.WriteRange(info.Data, srcOffset, srcPitch);
}
}
}
finally
{
texture.UnlockRectangle(0);
}
var dataRectangle = texture.Lock(0, LockFlags.None);
SlimDX.Direct3D9.Texture" enthält keine Definition für “Lock”, und es konnte keine Erweiterungsmethode “Lock” gefunden werden, die ein erstes Argument vom Typ “SlimDX.Direct3D9.Texture” akzeptiert (Fehlt eine Using-Direktive oder ein Assemblyverweis?).
doesn’t look like a big one, but i don’t know which usings or assembly references i need.
well then the bytes in your byte array are clearly in a different format.
suppose it’s really a bitmap (like saved to disk as *.bmp), which probably has some header and other stuff in it:
byte[]() tileObj = (byte[]())command.ExecuteScalar(); // what i get from a sqlite DB
using (var stream = new MemoryStream(tileObj))
{
var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
BitmapSource bitmapSource = decoder.Frames[0](0);
if (bitmapSource.Format != PixelFormats.Bgra32)
{
bitmapSource = new FormatConvertedBitmap(bitmapSource, PixelFormats.Bgra32, decoder.Palette, 0.0);
}
info.BitmapSource = bitmapSource;
}
...
// in update texture
var dataRectangle = texture.Lock(0, LockFlags.None);
try
{
var dstPitch = dataRectangle.Pitch;
var dstDataStream = dataRectangle.Data;
var dstBuffer = data.DataPointer;
info.BitmapSource.CopyPixels(Int32Rect.Empty, dstDataStream.DataPointer, (int)dstDataStream.Length, dstPitch);
}
finally
{
texture.UnlockRectangle(0);
}
oh and pls don’t post compile errors. i didn’t test this code, just wrote it down as i thought it should work. at least it does in another project when reading *.bmp
well probably the easiest way to get it going is changing the BitmapCacheOptions when creating the decoder. right now it’s set to None -> it will try to access the stream provided when creating the decoder. since we disposed the stream already (using (var stream = …)) you get that object disposed exception when reading the pixels.
other possibility would be to save the already decoded memory stream in your info class. so you’d decode (call CopyPixels) in evaluate and only copy the data in update texture.
and got correct data for the dynamic texture (as stated above). i thought, that this would have been impossible, if the data was compressed in any kind?
so, perhaps the data is in pure bitmap format, but has a .png file extension?
i’d guess so. the first 8 characters of a png should already mess up your output, since they’d be interpreted as pixels as well. maybe try to cache it to disk to analyse with more control?