I am trying to play sound from one speaker/earphone at a time. So I zero out the values for one side. but it is not working.
in a wav file the even values play from the right speaker/ hearphone and the old from the left right ?
so why it is not working
here is my code:
public override int Read(byte[] buffer, int offset, int sampleCount)
{
if (position == 0 && onetimeflag == false)
{
n2 = 0;
onetimeflag = true;
}
if (n2 >= Bufferlength && stopflag == false)
{
Dispose();
return 0;
}
float temp1;
for (int i = 0; i < (sampleCount / 4); i++)
{
if (Frequency_switch == true)
{
temp1 = (float)(Amplitude * Math.Sin(Math.PI * Frequency * n2 / 44100D));
Frequency_switch = false;
}
else
{
temp1 = (float)(Amplitude2 * Math.Sin((Math.PI * Frequency2 * n2) / 44100D));
Frequency_switch = true;
}
byte[] bytes = BitConverter.GetBytes(temp1);
buffer[i * 4 + 0] = bytes[0];
buffer[i * 4 + 1] = bytes[1];
buffer[i * 4 + 2] = bytes[2];
buffer[i * 4 + 3] = bytes[3];
tempSample++;
n2++;
}
return sampleCount;}} }
I am using the NAudio library
here is how I play the sound:
private void button1_Click(object sender, EventArgs e)
{
Play(1, 240, 0);
}
binaural_beats BBeats;
WaveOut waveout;
void Play(double Amp, double Left, double Right)
{
BBeats = new binaural_beats();
BBeats.Amplitude = Amp;
BBeats.Amplitude2 = Amp;
BBeats.Frequency = Left;
BBeats.Frequency2 = Right;
BBeats.Bufferlength = 44100 * 2 * 3;// will play for 3 sec
waveout = new WaveOut();
WaveChannel32 temp = new WaveChannel32(BBeats);
temp.PadWithZeroes = false;
waveout.Init(temp);
waveout.Play();
}
Related
Well, my question is pretty simple to understand, I'm trying to create a grid of chunks but on each step, I want to double the distance of a chunk.
Then, this is the code I have:
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class DrawLoDTest : MonoBehaviour
{
private List<Vector3> initialChunks;
public int chunkSize = 16;
public int lodLevels = 2;
public int width = 16;
public int height = 16;
private Color[] colorList;
// Start is called before the first frame update
private void Start()
{
}
// Update is called once per frame
private void Update()
{
}
private void Init()
{
if (initialChunks != null && initialChunks.Count > 0)
return;
colorList = new[] { Color.blue, Color.green, Color.yellow, Color.cyan, Color.magenta, Color.grey };
Debug.Log("Init test!");
initialChunks = new List<Vector3>(16 * 16);
for (var i = 0; i < width * height; i++)
{
var x = i % width;
var y = i / width;
initialChunks.Add(new Vector3(x * chunkSize - width * chunkSize / 2, 0, y * chunkSize - height * chunkSize / 2));
}
//Debug.Log(string.Join(Environment.NewLine, initialChunks.Select(v => v.ToString())));
}
private void OnDrawGizmos()
{
Init();
Gizmos.color = Color.red;
foreach (var chunk in initialChunks)
{
Gizmos.DrawWireCube(chunk, Vector3.one * chunkSize);
}
var ww = 0;
var ww2 = 0;
var sum = 0;
var halfChunkSize = chunkSize / 2;
var halfWidth = width * halfChunkSize;
var halfHeight = height * halfChunkSize;
for (var i = 1; i <= lodLevels; i++)
{
if (ww > 0)
++ww2;
var pow = (int)Mathf.Pow(2, i);
var w = width / pow;
var h = height / pow;
Gizmos.color = colorList[i - 1];
var oddSum = ww * chunkSize * pow;
for (var x = -1 - ww2; x <= w + ww2; x++)
{
for (var n = 0; n <= 1; n++)
{
var sign = n == 0 ? -1 : 1;
var chunk = new Vector3(
halfWidth - x * chunkSize * pow - halfChunkSize,
0,
halfHeight * sign - halfChunkSize - chunkSize * 2 * sign + oddSum * sign + sum * sign);
chunk.x -= pow * halfChunkSize;
for (var j = i + 1; j >= i; j--)
{
chunk.z += chunkSize * (int)Mathf.Pow(2, j) / 2 * sign;
}
Gizmos.DrawWireCube(chunk, Vector3.one * chunkSize * pow);
}
}
// TODO
if ((w + ww2 * 2 + 2) / 2 % 2 != 0)
{
Debug.Log($"[{i}, {ww}, {ww2}] W: {w} + {ww2} * 2 = {w + ww2 * 2} + 2 = {w + ww2 * 2 + 2} / 2 = {(w + ww2 * 2 + 2) / 2}");
if (ww == 0)
{
--i;
++ww;
}
else
{
ww = 0;
sum += oddSum;
}
}
else
{
if (ww2 > 0)
ww2 = 0;
}
}
}
}
A little bit of explanation:
First, I load a 16x16 chunk grid (initialChunks).
Then, I start a loop foreach lod level (I'm testing it for 6 levels).
Then, foreach axis I iterate its position.
Then, in a nested loop foreach axis I give a sign (a loop for 0 to 1, that converts into -1 and 1 for the sign).
Then, and this is the more complex thing, if the following row/column has an odd number of elements then I try to match the current row/column by doubling it, in that way non of the following corner will be half of the previous one, like the image below:
I have two main problems:
For some reason, sum and oddSum variables has the wrong input.
At certain levels, (for i >= 5) the logic is broken.
I'm currently trying to learn how to use multithreading in C# and I'm really struggling with letting the user choose how many threads to use from a UI.
I have, with the help of a few sources, written the code to mask a image using the median filter and now want to apply multithreading (1-64).
I know how threads work, but I'm struggling to find a way to implement it in this program.
Can someone please help me understand by not showing me the code needed, but explaining where threading should be implemented and how to allow the user to choose the amount of threads.
Code
class ExtBitmap
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing.Imaging;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Drawing2D;
namespace EilandFotoPRAK1
{
public static class ExtBitmap
{
public static Bitmap CopyToSquareCanvas(this Bitmap sourceBitmap, int canvasWidthLenght)
{
float ratio = 1.0f;
int maxSide = sourceBitmap.Width > sourceBitmap.Height ?
sourceBitmap.Width : sourceBitmap.Height;
ratio = (float)maxSide / (float)canvasWidthLenght;
Bitmap bitmapResult = (sourceBitmap.Width > sourceBitmap.Height ?
new Bitmap(canvasWidthLenght, (int)(sourceBitmap.Height / ratio))
: new Bitmap((int)(sourceBitmap.Width / ratio), canvasWidthLenght));
using (Graphics graphicsResult = Graphics.FromImage(bitmapResult))
{
graphicsResult.CompositingQuality = CompositingQuality.HighQuality;
graphicsResult.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphicsResult.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphicsResult.DrawImage(sourceBitmap,
new Rectangle(0, 0,
bitmapResult.Width, bitmapResult.Height),
new Rectangle(0, 0,
sourceBitmap.Width, sourceBitmap.Height),
GraphicsUnit.Pixel);
graphicsResult.Flush();
}
return bitmapResult;
}
public static Bitmap MedianFilter(this Bitmap sourceBitmap,
int matrixSize,
int bias = 0,
bool grayscale = false)
{
BitmapData sourceData =
sourceBitmap.LockBits(new Rectangle(0, 0,
sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb);
byte[] pixelBuffer = new byte[sourceData.Stride *
sourceData.Height];
byte[] resultBuffer = new byte[sourceData.Stride *
sourceData.Height];
Marshal.Copy(sourceData.Scan0, pixelBuffer, 0,
pixelBuffer.Length);
sourceBitmap.UnlockBits(sourceData);
if (grayscale == true)
{
float rgb = 0;
for (int k = 0; k < pixelBuffer.Length; k += 4)
{
rgb = pixelBuffer[k] * 0.11f;
rgb += pixelBuffer[k + 1] * 0.59f;
rgb += pixelBuffer[k + 2] * 0.3f;
pixelBuffer[k] = (byte)rgb;
pixelBuffer[k + 1] = pixelBuffer[k];
pixelBuffer[k + 2] = pixelBuffer[k];
pixelBuffer[k + 3] = 255;
}
}
int filterOffset = (matrixSize - 1) / 2;
int calcOffset = 0;
int byteOffset = 0;
List<int> neighbourPixels = new List<int>();
byte[] middlePixel;
for (int offsetY = filterOffset; offsetY <
sourceBitmap.Height - filterOffset; offsetY++)
{
for (int offsetX = filterOffset; offsetX <
sourceBitmap.Width - filterOffset; offsetX++)
{
byteOffset = offsetY *
sourceData.Stride +
offsetX * 4;
neighbourPixels.Clear();
for (int filterY = -filterOffset;
filterY <= filterOffset; filterY++)
{
for (int filterX = -filterOffset;
filterX <= filterOffset; filterX++)
{
calcOffset = byteOffset +
(filterX * 4) +
(filterY * sourceData.Stride);
neighbourPixels.Add(BitConverter.ToInt32(
pixelBuffer, calcOffset));
}
}
neighbourPixels.Sort();
middlePixel = BitConverter.GetBytes(
neighbourPixels[filterOffset]);
resultBuffer[byteOffset] = middlePixel[0];
resultBuffer[byteOffset + 1] = middlePixel[1];
resultBuffer[byteOffset + 2] = middlePixel[2];
resultBuffer[byteOffset + 3] = middlePixel[3];
}
}
Bitmap resultBitmap = new Bitmap(sourceBitmap.Width,
sourceBitmap.Height);
BitmapData resultData =
resultBitmap.LockBits(new Rectangle(0, 0,
resultBitmap.Width, resultBitmap.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb);
Marshal.Copy(resultBuffer, 0, resultData.Scan0,
resultBuffer.Length);
resultBitmap.UnlockBits(resultData);
return resultBitmap;
}
}
}
FrmPhoto class
---------------------------------------How the GUI Looks
public partial class FrmPhoto : Form
{
private Bitmap originalBitmap = null;
private Bitmap previewBitmap = null;
private Bitmap resultBitmap = null;
public FrmPhoto()
{
InitializeComponent();
cmbEdge.SelectedIndex = 0;
}
private void btnOpen_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Title = "Select an image file.";
dialog.Filter = "Png Images(*.png)|*.png|Jpeg Images(*.jpg)|*.jpg";
dialog.Filter += "|Bitmap Images(*.bmp)|*.bmp";
if (dialog.ShowDialog() == DialogResult.OK)
{
StreamReader streamReader = new StreamReader(dialog.FileName);
originalBitmap = (Bitmap)Bitmap.FromStream(streamReader.BaseStream);
streamReader.Close();
previewBitmap = originalBitmap.CopyToSquareCanvas(pix1.Width);
pix1.Image = previewBitmap;
}
}
private void ApplyFilter(bool preview)
{
if (previewBitmap == null || cmbEdge.SelectedIndex == -1)
{
return;
}
Bitmap selectedSource = null;
Bitmap bitmapResult = null;
if (preview == true)
{
selectedSource = previewBitmap;
}
else
{
selectedSource = originalBitmap;
}
if (selectedSource != null)
{
if (cmbEdge.SelectedItem.ToString() == "None")
{
bitmapResult = selectedSource;
}
else if (cmbEdge.SelectedItem.ToString() == "Median 3x3")
{
bitmapResult = selectedSource.MedianFilter(3);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 5x5")
{
bitmapResult = selectedSource.MedianFilter(5);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 7x7")
{
bitmapResult = selectedSource.MedianFilter(7);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 9x9")
{
bitmapResult = selectedSource.MedianFilter(9);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 11x11")
{
bitmapResult = selectedSource.MedianFilter(11);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 13x13")
{
bitmapResult = selectedSource.MedianFilter(13);
}
}
if (bitmapResult != null)
{
if (preview == true)
{
pix1.Image = bitmapResult;
}
else
{
resultBitmap = bitmapResult;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
ApplyFilter(true);
}
}
We can use Parallel.For method that will make parallelization for us.
We have to make all variables that are modified inside the parallel loop are local.
int filterOffset = (matrixSize - 1) / 2;
//int calcOffset = 0;
//int byteOffset = 0;
//List<int> neighbourPixels = new List<int>();
//byte[] middlePixel;
var w = sourceBitmap.Width - filterOffset;
for (int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++)
{
Parallel.For(filterOffset, w, offsetX =>
{
var byteOffset = offsetY * sourceData.Stride + offsetX * 4; // local
var neighbourPixels = new List<int>(); // local
//neighbourPixels.Clear();
for (int filterY = -filterOffset; filterY <= filterOffset; filterY++)
{
for (int filterX = -filterOffset; filterX <= filterOffset; filterX++)
{
var calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); // local
neighbourPixels.Add(BitConverter.ToInt32(pixelBuffer, calcOffset));
}
}
neighbourPixels.Sort();
var middlePixel = BitConverter.GetBytes(neighbourPixels[filterOffset]); // local
resultBuffer[byteOffset] = middlePixel[0];
resultBuffer[byteOffset + 1] = middlePixel[1];
resultBuffer[byteOffset + 2] = middlePixel[2];
resultBuffer[byteOffset + 3] = middlePixel[3];
});
};
This gives more than a two time increase in performance on my machine (2 physical cores, 4 logical).
Parallelization of the outer loop would certainly give more acceleration. However, to make it much more difficult.
In a similar way it is possible to make a parallelization of the grayscale filter.
I am trying to use libtiff.net to read elevation data from a GeoTIFF file.
So far I have mostly just been able to read metadata from the file using the example at libtiff.net's webpage.
But howto read elevation data I do not understand... I tried first reading with Tiff.ReadScanline() as described here but the file I have seems to be stored differently (probably in tiles if I understand it correctly)
Here is the metadata (as far as I have been able to read) (the tiff file is from the danish terrain elevation data set):
Tiff c:\Users***\DTM_1km_6170_500.tif, page 0 has following tags set:
IMAGEWIDTH System.Int32 : 2500
IMAGELENGTH System.Int32 : 2500
BITSPERSAMPLE System.Int16 : 32
COMPRESSION BitMiracle.LibTiff.Classic.Compression : ADOBE_DEFLATE
PHOTOMETRIC BitMiracle.LibTiff.Classic.Photometric : MINISBLACK
STRIPOFFSETS System.UInt64[] : System.UInt64[]
SAMPLESPERPIXEL System.Int16 : 1
STRIPBYTECOUNTS System.UInt64[] : System.UInt64[]
PLANARCONFIG BitMiracle.LibTiff.Classic.PlanarConfig : CONTIG
PREDICTOR BitMiracle.LibTiff.Classic.Predictor : FLOATINGPOINT
TILEWIDTH System.Int32 : 256
TILELENGTH System.Int32 : 256
TILEOFFSETS System.UInt64[] : System.UInt64[]
TILEBYTECOUNTS System.UInt64[] : System.UInt64[]
SAMPLEFORMAT BitMiracle.LibTiff.Classic.SampleFormat : IEEEFP
DATATYPE System.Int16 : 3
GEOTIFF_MODELPIXELSCALETAG System.Int32 : 3 GEOTIFF_MODELPIXELSCALETAG
System.Byte[] : Ù?Ù?
GEOTIFF_MODELTIEPOINTTAG System.Int32 : 6 GEOTIFF_MODELTIEPOINTTAG
System.Byte[] : A ^WA
34735 System.Int32 : 36 34735 System.Byte[] :
± ± #° èd )#
34736 System.Int32 : 3 34736 System.Byte[] :
34737 System.Int32 : 30 34737 System.Byte[] : ETRS89 / UTM zone
32N|ETRS89|
42113 System.Int32 : 6 42113 System.Byte[] : -9999
The code I have written so far is as follows:
namespace GeoTIFFReader
{
public class GeoTIFF
{
private double[,] heightmap;
private double dx;
private double dy;
private double startx;
private double starty;
public GeoTIFF(string fn)
{
using (Tiff tiff = Tiff.Open(fn, "r"))
{
if (tiff == null)
{
// Error - could not open
return;
}
int width = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
int height = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
heightmap = new double[width, height];
FieldValue[] modelPixelScaleTag = tiff.GetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG);
FieldValue[] modelTiePointTag = tiff.GetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG);
byte[] modelPixelScale = modelPixelScaleTag[1].GetBytes();
dx = BitConverter.ToDouble(modelPixelScale, 0);
dy = BitConverter.ToDouble(modelPixelScale, 8) * -1;
byte[] modelTransformation = modelTiePointTag[1].GetBytes();
double originLon = BitConverter.ToDouble(modelTransformation, 24);
double originLat = BitConverter.ToDouble(modelTransformation, 32);
startx = originLon + dx / 2.0;
starty = originLat + dy / 2.0;
double curx = startx;
double cury = starty;
FieldValue[] bitsPerSampleTag = tiff.GetField(TiffTag.BITSPERSAMPLE);
FieldValue[] tilewtag = tiff.GetField(TiffTag.TILEWIDTH);
FieldValue[] tilehtag = tiff.GetField(TiffTag.TILELENGTH);
int tilew = tilewtag[0].ToInt();
int tileh = tilehtag[0].ToInt();
var tile = new byte[tilew*tileh];
//var scanline = new byte[tiff.ScanlineSize()]; Does not work... wrong format
for (int il = 0; il < height; il++)
{
//tiff.ReadScanline(scanline, il); // Load il'th line of data
for (int ir = 0; ir < width; ir++)
{
// Here I would like to read each pixel data that contains elevation in gray-scale in f32 as far I as I understand from metadata
//object value = scanline[ir];
//heightmap[ir, il] = double.Parse(value.ToString());
}
}
Console.WriteLine(heightmap.ToString());
}
}
}
}
So if anyone knows howto extract this data, that would be very much appreciated.
So I stumbled across some hinting that lead me to find an answer to the specific question..:
int tileSize = tiff.TileSize();
for (int iw = 0; iw < nWidth; iw += tilew)
{
for (int ih = 0; ih < nHeight; ih += tileh)
{
byte[] buffer = new byte[tileSize];
tiff.ReadTile(buffer, 0, iw, ih, 0, 0);
for (int itw = 0; itw < tilew; itw++)
{
int iwhm = ih + itw;
if (iwhm > nWidth - 1)
{
break;
}
for (int ith = 0; ith < tileh; ith++)
{
int iyhm = iw + ith;
if (iyhm > nHeight - 1)
{
break;
}
heightMap[iwhm, iyhm] =
BitConverter.ToSingle(buffer, (itw * tileh + ith) * 4);
}
}
}
}
EDIT 2018-09-20:
#Graviton - Sorry for the long response time.. but here is the complete class I have used with a constructor that takes the filename as input and populates the heightMap (but #Nazonokaizijin looks a bit nicer and slimmer):
using System;
using BitMiracle.LibTiff.Classic;
using System.IO;
namespace GeoTIFFReader
{
public class GeoTIFF
{
private float[,] heightMap;
public float[,] HeightMap
{
get { return heightMap; }
private set { heightMap = value; }
}
private int nWidth;
public int NWidth
{
get { return nWidth; }
private set { nWidth = value; }
}
private int nHeight;
public int NHeight
{
get { return nHeight; }
private set { nHeight = value; }
}
private double dW;
public double DW
{
get { return dW; }
private set { dW = value; }
}
private double dH;
public double DH
{
get { return dH; }
private set { dH = value; }
}
private double startW;
public double StartW
{
get { return startW; }
private set { startW = value; }
}
private double startH;
public double StartH
{
get { return startH; }
private set { startH = value; }
}
public GeoTIFF(string fn)
{
using (Tiff tiff = Tiff.Open(fn, "r"))
{
if (tiff == null)
{
// Error - could not open
return;
}
nWidth = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
nHeight = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
heightMap = new float[nWidth, nHeight];
FieldValue[] modelPixelScaleTag = tiff.GetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG);
FieldValue[] modelTiePointTag = tiff.GetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG);
byte[] modelPixelScale = modelPixelScaleTag[1].GetBytes();
dW = BitConverter.ToDouble(modelPixelScale, 0);
dH = BitConverter.ToDouble(modelPixelScale, 8) * -1;
byte[] modelTransformation = modelTiePointTag[1].GetBytes();
double originLon = BitConverter.ToDouble(modelTransformation, 24);
double originLat = BitConverter.ToDouble(modelTransformation, 32);
startW = originLon + dW / 2.0;
startH = originLat + dH / 2.0;
FieldValue[] tileByteCountsTag = tiff.GetField(TiffTag.TILEBYTECOUNTS);
long[] tileByteCounts = tileByteCountsTag[0].TolongArray();
FieldValue[] bitsPerSampleTag = tiff.GetField(TiffTag.BITSPERSAMPLE);
int bytesPerSample = bitsPerSampleTag[0].ToInt() / 8;
FieldValue[] tilewtag = tiff.GetField(TiffTag.TILEWIDTH);
FieldValue[] tilehtag = tiff.GetField(TiffTag.TILELENGTH);
int tilew = tilewtag[0].ToInt();
int tileh = tilehtag[0].ToInt();
int tileWidthCount = nWidth / tilew;
int remainingWidth = nWidth - tileWidthCount * tilew;
if (remainingWidth > 0)
{
tileWidthCount++;
}
int tileHeightCount = nHeight / tileh;
int remainingHeight = nHeight - tileHeightCount * tileh;
if (remainingHeight > 0)
{
tileHeightCount++;
}
int tileSize = tiff.TileSize();
for (int iw = 0; iw < nWidth; iw += tilew)
{
for (int ih = 0; ih < nHeight; ih += tileh)
{
byte[] buffer = new byte[tileSize];
tiff.ReadTile(buffer, 0, iw, ih, 0, 0);
for (int itw = 0; itw < tilew; itw++)
{
int iwhm = ih + itw;
if (iwhm > nWidth - 1)
{
break;
}
for (int ith = 0; ith < tileh; ith++)
{
int iyhm = iw + ith;
if (iyhm > nHeight - 1)
{
break;
}
heightMap[iwhm, iyhm] =
BitConverter.ToSingle(buffer, (itw * tileh + ith) * 4);
}
}
}
}
}
}
}
}
You can do it something like this:
private void ReadTiff()
{
Tiff tiff = Tiff.Open("myfile.tif", "r");
if (tiff == null)
return;
//Get the image size
int imageWidth = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
int imageHeight = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
//Get the tile size
int tileWidth = tiff.GetField(TiffTag.TILEWIDTH)[0].ToInt();
int tileHeight = tiff.GetField(TiffTag.TILELENGTH)[0].ToInt();
int tileSize = tiff.TileSize();
//Pixel depth
int depth = tileSize / (tileWidth * tileHeight);
byte[] buffer = new byte[tileSize];
for (int y = 0; y < imageHeight; y += tileHeight)
{
for (int x = 0; x < imageWidth; x += tileWidth)
{
//Read the value and store to the buffer
tiff.ReadTile(buffer, 0, x, y, 0, 0);
for (int kx = 0; kx < tileWidth; kx++)
{
for (int ky = 0; ky < tileHeight; ky++)
{
//Calculate the index in the buffer
int startIndex = (kx + tileWidth * ky) * depth;
if (startIndex >= buffer.Length)
continue;
//Calculate pixel index
int pixelX = x + kx;
int pixelY = y + ky;
if (pixelX >= imageWidth || pixelY >= imageHeight)
continue;
//Get the value for the target pixel
double value = BitConverter.ToSingle(buffer, startIndex);
}
}
}
}
tiff.Close();
}
It has a lib (in c#) complementary to LibTiff that makes the elevation query given a latitude/longitude, available at GeoTiffCOG:
GeoTiff geoTiff = new GeoTiff(file_tiff);
double value = geoTiff.GetElevationAtLatLon(latitude, longitude);
It also supports Cloud Optimized GeoTiff (COG) by adding URI as an argument.
I believe the problem is the PREDICTOR. Instead of placing the data in the file, it is LZW encoding of the differences in the data, with FLOATINGPOINT predictor. This was proprietary with Adobe. I have been searching for code do decrypt PREDICTOR_FLOATINGPOINT, myself. I think this github link
may have library code that will read and decode it.
How can I draw only one channel. My example work for mono, but sound is stereo. I want here show only left or only right channel.
protected override void OnPaint(PaintEventArgs e)
{
if (waveStream != null)
{
waveStream.Position = 0;
int bytesRead;
byte[] waveData = new byte[samplesPerPixel * bytesPerSample];
waveStream.Position = startPosition + (e.ClipRectangle.Left * bytesPerSample * samplesPerPixel);
using (Pen linePen = new Pen(PenColor, PenWidth))
{
for (float x = e.ClipRectangle.X; x < e.ClipRectangle.Right; x += 1)
{
short low = 0;
short high = 0;
bytesRead = waveStream.Read(waveData, 0, samplesPerPixel * bytesPerSample);
if (bytesRead == 0)
break;
for (int n = 0; n < bytesRead; n+=2)
{
short sample = BitConverter.ToInt16(waveData, n);
if (sample < low) low = sample;
if (sample > high) high = sample;
}
float lowPercent = ((((float)low) - short.MinValue) / ushort.MaxValue);
float highPercent = ((((float)high) - short.MinValue) / ushort.MaxValue);
e.Graphics.DrawLine(linePen, x, this.Height * lowPercent, x, this.Height * highPercent);
}
}
}
base.OnPaint(e);
}
I read, 1-3-5... for first channel, and 2-4-6... for second channel. But if in for loop change this, I got different graph, but not correct. How can I fix that?
Use WaveWiever Painter. Work real-time and for two channels.
My problem is that clicks only get registers on the lower right corner and in some cases not even there it seems to get worse the longer you stray from the 0.0 and the likes the worse it gets.
public void Render(SpriteBatch B, Camera C)
{
Vector2 firstSquare = new Vector2(C.Position.X / 32, C.Position.Y / 32);
int firstX = (int)firstSquare.X;
int firstY = (int)firstSquare.Y;
Vector2 squareOffset = new Vector2(C.Position.X % 32, C.Position.Y % 32);
int offsetX = (int)squareOffset.X;
int offsetY = (int)squareOffset.Y;
for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 26; x++)
{
Tile T = GetTile(x + firstX, y + firstY);
if (T == null)
{
continue;
}
T.RenderWithCamera(B,new Vector2((x*32)-offsetX,(y*32)-offsetY));
}
}
public void CheckClick(float mx, float my,Camera C)
{
Vector2 firstSquare = new Vector2(C.Position.X / 32, C.Position.Y / 32);
int x = (int)firstSquare.X;
int y = (int)firstSquare.Y;
Vector2 squareOffset = new Vector2(C.Position.X % 32, C.Position.Y % 32);
int offsetX = (int)squareOffset.X;
int offsetY = (int)squareOffset.Y;
int vx = (int)mx / 32;
int vy = (int)my / 32;
float x1 = vx + x;
float y1 = vy + y;
int maxX, maxY;
maxX = C.Width / 32;
maxY = C.Height / 32;
Console.WriteLine("MAX_X:" + maxX + "MAX_Y:" + maxY);
Tile T = GetTile(x1, y1);
Rectangle A = new Rectangle((int)mx, (int)my, 1, 1);
if (T == null)
{ Console.WriteLine("No Tile found"); return; }
if (T.IsInside(A))
{
Console.WriteLine("Not inside?");
Tile S = null;
S = new Wall((int)x1, (int)y1, 0);
if (S != null)
{
tiles.Add(S);
tiles2[(int)T.pos.X, (int)T.pos.Y] = S;
}
}
Console.WriteLine("Clicked Tile at X:" + T.pos.X + "Y:" + T.pos.Y);
}
public bool IsInside(Rectangle B) // TILE
{
Rectangle rectA = new Rectangle((int)Last_pos.X, (int)Last_pos.Y, icon.Width, icon.Height);
Console.WriteLine("A:" + rectA.X + "A.y:" + rectA.Y + "B.X:" + B.X + "B.Y:" + B.Y);
if(rectA.Intersects(B))
{
return true;
}
else
return false;
}
Here's how I like to handle clicking a tilemap.
int xTile = Math.floor((Mouse.X + CameraBounds.left) / Tile.width);
int yTile = Math.floor((Mouse.Y + CameraBounds.top) / Tile.height);