I have an image (which is a Sprite) that I store it in a byte array.
I would like to extract only the bytes that relate to a specific place and size within this byte array so that I can create a new image, basically a crop.
I am using C# and compact cf. I could use get pixel and save each value to a byte array and then 'read' the portion i am interested back. I know I can use LockBitmap() to make this quicker. I would normally use Aforge and/or Emgu but as I say I am using the compact cf framework 2.
I would be interested in any known ways to do this.
Thanks
Additional.
Following on the link below I would like to know whether there is an alternative (like a buffer copy) to this iterative piece of code?
//Iterate the selected area of the original image, and the full area of the new image
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width * BPP; j += BPP)
{
int origIndex = (startX * rawOriginal.Stride) + (i * rawOriginal.Stride) + (startY * BPP) + (j);
int croppedIndex = (i * width * BPP) + (j);
//copy data: once for each channel
for (int k = 0; k < BPP; k++)
{
croppedBytes[croppedIndex + k] = origBytes[origIndex + k];
}
}
}
I understand that this is an old question, but here's my take on it:
public static byte[] CropImageArray(byte[] pixels, int sourceWidth, int bitsPerPixel, Int32Rect rect)
{
var blockSize = bitsPerPixel / 8;
var outputPixels = new byte[rect.Width * rect.Height * blockSize];
//Create the array of bytes.
for (var line = 0; line <= rect.Height - 1; line++)
{
var sourceIndex = ((rect.Y + line) * sourceWidth + rect.X) * blockSize;
var destinationIndex = line * rect.Width * blockSize;
Array.Copy(pixels, sourceIndex, outputPixels, destinationIndex, rect.Width * blockSize);
}
return outputPixels;
}
You'll need to know the bits per pixel and the width. You'll be using one for instead of two.
I have some more links for you
Try out if you find you solution or it helps you in any way
1)http://www.codeproject.com/Articles/33838/Image-Processing-using-C
2)http://codenicely.blogspot.in/2012/03/how-to-crop-image-in-c.html
Related
I'm working on a game modification for a third party game (a so called "mod"), and I want to add the player to an array.
I will explain the process of how it works. My code looks like this:
int numElements = 20;
int arrSize = numElements * 2 + 2;
Ped peds[arrSize];
peds[0] = numElements;
int countPeds = GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), peds, -1);
The game function called GET_PED_NEARBY_PEDS will populate the peds array with IDs of the pedestrians walking around the PLAYER_PED_ID (our player).
My goal here is to also add our player to this array aswell. Right now, it only gathers the pedestrians around the player, and I want the player to be included in this array aswell.
I came to the conclusion that I should create a new array, and add the PLAYER_PED_ID to this new array, like so:
Ped newpeds[arrSize + 1];
for (int i = 0; i < arrSize; i++) newpeds[i] = peds[i];
newpeds[arrSize + 1] = PLAYER_PED_ID();
And then instead of using the peds array in my code, I will be using newpeds. But for some reason the modifications don't affect the player, but only the pedestrians around the player (like the first code example).
This is what my full code looks like:
int numElements = 20;
int arrSize = numElements * 2 + 2;
Ped peds[arrSize];
peds[0] = numElements;
int countPeds = GET_PED_NEARBY_PEDS(pedID, peds, -1);
Ped newpeds[arrSize + 1];
for (int i = 0; i < arrSize; i++) newpeds[i] = peds[i];
newpeds[arrSize + 1] = PLAYER_PED_ID();
for (int i = 0; i < countPeds; i++) {
Ped ped = newpeds[i * 2 + 2];
//...
}
How can I add the player to the array? Could it have something to do with the math? Any help is appreciated. :)
This may be because you are trying to add PLAYER_PED_ID() at wrong index.
for (int i = 0; i < arrSize; i++) newpeds[i] = peds[i];
newpeds[arrSize + 1] = PLAYER_PED_ID();
You should be adding PLAYER_PED_ID() at :
newpeds[arrSize] = PLAYER_PED_ID();
I have a struct that basically has these contents:
typedef struct {
unsigned int width, height;
float *r, *g, *b;
} image;
Using the FreeImage.h library I am able to open a certain image and associate the pixels with its RGB colours. So the code is as follows:
imagem open_image(char *name_of_file) {
FIBITMAP *bitmapIn;
int x, y;
RGBQUAD color;
image I;
bitmapIn = FreeImage_Load(FIF_JPEG, name_of_file, 0);
if (bitmapIn == 0) {
printf("Error! File not found - %s\n", name_of_file);
} else {
printf("File found!\n");
}
x = FreeImage_GetWidth(bitmapIn);
y = FreeImage_GetHeight(bitmapIn);
I.width = x;
I.height = y;
I.r = malloc(sizeof(float) * x * y);
I.g = malloc(sizeof(float) * x * y);
I.b = malloc(sizeof(float) * x * y);
for (int i=0; i<x; i++) {
for (int j=0; j <y; j++) {
int idx;
FreeImage_GetPixelColor(bitmapIn, i, j, &color);
idx = i + (j*x);
I.r[idx] = color.rgbRed;
I.g[idx] = color.rgbGreen;
I.b[idx] = color.rgbBlue;
}
}
return I;
}
So now when I call the function in my main file like:
image img = open_image("file_name");
I have my image "map" in my reference named img.
Basically what I want to know is what is the best way to make a copy of this img so that I can apply a filter in this buffer img, for exemple a blur filter. That way when I get the surrounding pixels values to write to the central one, it is always the original pixels so get the pixels from "img" and write them with the filter to the "img_buffer".
I guess I could just make another reference named img_buff and call the open_image function again but that takes to much real and user time.
So how would you suggest I made the copy? From my research I found that memcpy() maybe won't do the trick since it gives me a shallow copy but not to sure about it.
Any suggestion that won't take to much more real/user time is welcome!
If you want to improve performances,you should try to avoid copies which are time-consuming specially for large arrays.
But I assume you can't, so there is a solution :
Image imgCopy;
imgCopy.width = img.width
imgCopy.height = img.height
In a first time you allocate memory :
imgCopy.r = (float*)malloc(sizeof(float) * imgCopy.width * imgCopy.height );
imgCopy.g = (float*)malloc(sizeof(float) * imgCopy.width * imgCopy.height );
imgCopy.b = (float*)malloc(sizeof(float) * imgCopy.width * imgCopy.height );
Then you can copy the pointer's content :
*(imgCopy.r) = *(img.r);
*(imgCopy.g) = *(img.r);
*(imgCopy.b) = *(img.r);
I am writing a windows forms application. I have an Image, received from CCD camera. The camera takes 12 bit grayscale tiff – 2 bytes per pixel. To receive it I am using WIA(windows image acquisition). I can make a byte array from the image data. After that I need to display the image in picturebox. When shown in picturebox, the image is too dark. Also, the created bitmap is Format32bppArgb. Do I lose quality, when creating the bitmap and how can I make the needed bitmap format? I am extremely new to image processing and any help will be great. I have read many forum posts on the topic of conversion between the formats, but with no luck so far.
So any ideas how to receive 16 bit grayscale bitmap from what I have so far?
Edit: This now is working:
private void btnAdvancedTestSnap_Click(object sender, EventArgs e)
{
WIA.CommonDialog _dialog = new CommonDialogClass();
WIA.Device _camera = _dialog.ShowSelectDevice(WIA.WiaDeviceType.CameraDeviceType, false, false);
ImageFile imageFile = (ImageFile)_camera.Items[1].Transfer(EnvFormatID.wiaFormatTIFF);
Byte[] receivedBytes = (byte[])imageFile.FileData.get_BinaryData();
int bytecount = receivedBytes.Length;
int width = imageFile.Width;
int height = imageFile.Height;
int dimension = width * height * 2;//number of bytes representing the image - 2 bytes per pixel
int startImgBytes = bytecount - dimension;
startImgBytes += 1;// from which position of the big array to start making pixel values
byte[] imageBytes = new byte[dimension]; //byte array with only bytes,representing the picture
int j = 0;
for (int i = startImgBytes; i < receivedBytes.Length; i++)//filling the only pixel byte data array
{
imageBytes[j] = receivedBytes[i];
j++;
}
int pixDimension = width * height; //number of pixels in the image
int[] pixVal = new int[pixDimension];
int z = 0;
for (int i = 0; i < imageBytes.Length; i+=2)
{
int res = (imageBytes[i] * 0x100) + imageBytes[i + 1];//int value of the pixel, 2 bytes per pixel
int pix = (res * 255) / 4095;// scalling down to 8 bit value
pixVal[z] = pix;
z++;
}
Bitmap newImage = new Bitmap(width, height, PixelFormat.Format24bppRgb);
Color p;
//grayscale
int counter = 0;
for (int y = 0; y < height; y++)//height
{
for (int x = 0; x < width; x++)//width
{
int val = pixVal[counter];
newImage.SetPixel(x,y,Color.FromArgb(255,val,val,val));
counter++;
}
}
pbAdvanced.Image = newImage; //show the image in picture box
But this method is very slow for high resolution. Any ideas how to improve the speed. I read examples with Marshal.Copy and lockbits, but in all examples they use a source image and copy to new. Any help will be greately appreciated
I'm trying to implement simple delay/reverb described in this post https://stackoverflow.com/a/5319085/1562784 and I have a problem. On windows where I record 16bit/16khz samples and get 8k samples per recording callback call, it works fine. But on linux I get much smaller chunks from soundcard. Something around 150 samples. Because of that I modified delay/reverb code to buffer samples:
#define REVERB_BUFFER_LEN 8000
static void reverb( int16_t* Buffer, int N)
{
int i;
float decay = 0.5f;
static int16_t sampleBuffer[REVERB_BUFFER_LEN] = {0};
//Make room at the end of buffer to append new samples
for (i = 0; i < REVERB_BUFFER_LEN - N; i++)
sampleBuffer[ i ] = sampleBuffer[ i + N ] ;
//copy new chunk of audio samples at the end of buffer
for (i = 0; i < N; i++)
sampleBuffer[REVERB_BUFFER_LEN - N + i ] = Buffer[ i ] ;
//perform effect
for (i = 0; i < REVERB_BUFFER_LEN - 1600; i++)
{
sampleBuffer[i + 1600] += (int16_t)((float)sampleBuffer[i] * decay);
}
//copy output sample
for (i = 0; i < N; i++)
Buffer[ i ] = sampleBuffer[REVERB_BUFFER_LEN - N + i ];
}
This results in white noise on output, so clearly I'm doing something wrong.
On linux, I record in 16bit/16khz, same like on Windows and I'm running linux in VMWare.
Thank you!
Update:
As indicated in answered post, I was 'reverbing' old samples over and over again. Simple 'if' sovled a problem:
for (i = 0; i < REVERB_BUFFER_LEN - 1600; i++)
{
if((i + 1600) >= REVERB_BUFFER_LEN - N)
sampleBuffer[i + 1600] += (int16_t)((float)sampleBuffer[i] * decay);
}
Your loop that performs the actual reverb effect will be performed multiple times on the same samples, on different calls to the function. This is because you save old samples in the buffer, but you perform the reverb on all samples each time. This will likely cause them to overflow at some point.
You should only perform the reverb on the new samples, not on ones which have already been modified. I would also recommend checking for overflow and clipping to the min/max values instead of wrapping in that case.
A probably better way to perform reverb, which will work for any input buffer size, is to maintain a circular buffer of size REVERB_SAMPLES (1600 in your case), which contains the last samples.
void reverb( int16_t* buf, int len) {
static int16_t reverb_buf[REVERB_SAMPLES] = {0};
static int reverb_pos = 0;
for (int i=0; i<len; i++) {
int16_t new_value = buf[i] + reverb_buf[reverb_pos] * decay;
reverb_buf[reverb_pos] = new_value;
buf[i] = new_value;
reverb_pos = (reverb_pos + 1) % REVERB_SAMPLES;
}
}
i am coding in C and i have to work with png images, so i work with libpng library. In my project i use this structure:
png_bytep *row_pointers; /* <-- to declare the pointer that will contain the image
and this to initialize the pointer to contain the image. */
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for(int y = 0; y < height; y++) {
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info));
}
My problem is: after this piece of code my image is copyed in row_pointers and i want to copy it in a png_byte map[x][y] so i can work easly pixel for pixel.
Someone can help me?
Thanks
Ok. That is pointer to pointer!
png_bytep = pointer to png_byte
If you eliminate png_bytep and just use png_byte your code will look like this.
int height = 10;
int width = 20;
png_byte **row_pointers;
row_pointers = (png_byte**)malloc(sizeof(png_byte*) * height); <-- This is basically your number of rows.. ie height of your matrix.
for(int y = 0; y < height; y++)
{
row_pointers[y] = (png_byte*)malloc(sizeof(png_byte)*width); <-- This is representing number of elements in each row.. so width.
}
Assuming your structure have two ints x and y. you must be filing data as below..
for(int i=0;i< height;i++)
{
for (int j=0;j<width;j++)
{
row_pointers[i][j].x = i*j;
row_pointers[i][j].y = i*j;
}
}
Assuming your map also have similar structure. This is how you copy data..
for(int i=0;i< height;i++)
{
for (int j=0;j<width;j++)
{
map[i][j].x = row_pointers[i][j].x;
map[i][j].y = row_pointers[i][j].y;
}
}
Have a look at pnm2png.c in libpng's contrib/pngminus directory.
In this code, "png_pixels" is a simple array that holds all the pixels, and row_pointers is an array of pointers that point to the beginning of each row within png_pixels:
/* row_bytes is the width x number of channels x (bit-depth / 8) */
row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))
/* set the individual row_pointers to point at the correct offsets */
for (i = 0; i < (height); i++)
row_pointers[i] = png_pixels + i * row_bytes;
/* now we can go ahead and just read the whole image */
png_read_image (png_ptr, row_pointers);
Once png_read_image completes, you can easily work with your pixels in the png_pixels array.
Notice that there is only one "malloc", which allocates png_pixels. Instead of doing a separate "malloc" for each row, this code calculates the values of the row_pointers.