How to read the end of image file stream in VB6 - image

There is a code written by another programmer which I want to improve. The purpose of the module is to get a live image stream from camera and to display it in the picture window. It is doing it over the TCP IP connection. Here is how it is done
Get the
Private Sub DataArrival(ByVal bytes As Long)
Dim str As String
' check the socket for data
camera.GetData str
Dim str As String
While InStr(str, Terminator) <> 0
**Do some processing and put only the data in the variable str
str = Mid(str, index, 1000)
lImgSize = lImgSize + Len(str)
strImg = strImg + str
If lImageSize >= 1614414 Then
Dim fileno As Integer
fileno = FreeFile()
Open ".\Imagefile.txt" For Output As #intFileNo
Print #fileno , strImg
Close #fileno
End If
End Sub
I have an input image stream coming and converting it to string and I am calculating the size to check the end of the image to write it in to a file. But the hardcoded value does not guarantee the end of file always. Sometimes If the image size is little less than the size, my picture box is not update with a live image.
EDIT:
This is what the image.txt file contains.
1
1575020 // file size header
424D36040C0000000000360400002800000000040000000300000100080000000000000000000000
--data--
--data--
020303030203010302010202030002030203020302020302030202030102
3BFB
Is there any other efficient way to handle this in VB6?

You need to agree a full protocol that specifies how you're going to pass the image data and the image data length over the TCP stream.
In your receiver, you then start reading the data into a buffer until you get enough data to contain your headers. At this point, you can parse out the data length and then continue reading data into your data buffer until you at least that amount of data.
When you finally get all the data, you can decode and save out the image data then either close the stream (if it's a one off) or start form the beginning and parse out the file header.
You can find a bit more info on the #VB wiki.

Related

Ruby script which can replace a string in a binary file to a different, but same length string?

I would like to write a Ruby script (repl.rb) which can replace a string in a binary file (string is defined by a regex) to a different, but same length string.
It works like a filter, outputs to STDOUT, which can be redirected (ruby repl.rb data.bin > data2.bin), regex and replacement can be hardcoded. My approach is:
#!/usr/bin/ruby
fn = ARGV[0]
regex = /\-\-[0-9a-z]{32,32}\-\-/
replacement = "--0ca2765b4fd186d6fc7c0ce385f0e9d9--"
blk_size = 1024
File.open(fn, "rb") {|f|
while not f.eof?
data = f.read(blk_size)
data.gsub!(regex, str)
print data
end
}
My problem is that when string is positioned in the file that way it interferes with the block size used by reading the binary file. For example when blk_size=1024 and my 1st occurance of the string begins at byte position 1000, so I will not find it in the "data" variable. Same happens with the next read cycle. Should I process the whole file two times with different block size to ensure avoiding this worth case scenario, or is there any other approach?
I would posit that a tool like sed might be a better choice for this. That said, here's an idea: Read block 1 and block 2 and join them into a single string, then perform the replacement on the combined string. Split them apart again and print block 1. Then read block 3 and join block 2 and 3 and perform the replacement as above. Split them again and print block 2. Repeat until the end of the file. I haven't tested it, but it ought to look something like this:
File.open(fn, "rb") do |f|
last_block, this_block = nil
while not f.eof?
last_block, this_block = this_block, f.read(blk_size)
data = "#{last_block}#{this_block}".gsub(regex, str)
last_block, this_block = data.slice!(0, blk_size), data
print last_block
end
print this_block
end
There's probably a nontrivial performance penalty for doing it this way, but it could be acceptable depending on your use case.
Maybe a cheeky
f.pos = f.pos - replacement.size
at the end of the while loop, just before reading the next chunk.

Limit size of output file and create additional files if needed with Ruby

I have a script that outputs URLs based on input data. Each line of input generates roughly 20 URLs. This output is then used to upload to Akamai Content Control. However, Akamai has a limit on file size set to 50KB.
I know I can write a URL and then check file size. If file size breaks buffer, close that file and create a new one and repeat.
I am ultimately curious if there is a far more elegant way to handle this within Ruby with less overhead/code.
Thanks
Before writing each line check if file size + line size is less then limit. Write to file or create new one accordingly.
index = 2;
f = File.new('output_file.txt', 'w')
while(there_is_new_output_to_write) do #get new line
if(f.size + output_line.size > LIMIT) do #if total size is too big
Fileutils.cp('output_file.txt','output_file' + index + '.txt') #copy
index = index + 1 #increment index for new file
f = File.new('output_file.txt', 'w') #override output file
end
f.puts(output_line) #write new line
end
#here You will have index -1 files
#that is if index is 4, then you will have output_file.txt, output_file2.txt, output_file3.txt,
#but NOT output_file4.txt!
Alternatively if that is not a problem You can use some good archiving tool out there to splice files to 50kb size for You.

VB Text to Array

Hi I have a text file that I would like to assign to an array and then assign each item in the array to a custom defined variable. When I open the file in notepad, it seems as if the data is on one line and there's about 10 tabs worth of space until the next piece of information.
I use the following code to successfully view the information in a msgbox as MyArray(i).
In my code example, all the information is listed in MyArray(0) and MyArray(1) gives me an error of subscript out of range. The information in the text file seems to appear as if it were delimited by vbCrLf but that does not work either...
Is there a way to trim the spaces from MyArray(0) and then re-assign the individual data to a new array? Here's what the first two pieces of information look like from my file:
967042
144890
Public Function ReadTextFile()
Dim TextFileData As String, myArray() As String, i As Long
Dim strCustomVariable1 As String
Dim strCustomVariable2 As String
'~~> Open file as binary
Open "C:\textfile\DATA-SND" For Binary As #1
'~~> Read entire file's data in one go
TextFileData = Space$(LOF(1))
Get #1, , TextFileData
'~~> Close File
Close #1
'~~> Split the data in seperate lines
myArray() = Split(TextFileData, vbCrLf)
For i = 0 To UBound(myArray())
MsgBox myArray(i)
Next
End Function
Under normal circumstances, I'd suggest that you use Line Input instead:
Open "C:\textfile\DATA-SND" For Input As #1
Do Until EOF(1)
Redim Preserve myArray(i)
Line Input #1, myArray(i)
i = i + 1&
Loop
Close #1
However, you're likely dealing with different end-line characters. You can use your existing code and just change it to use vbCr or vbLf instead of vbCrLf. My method assumes that your end-line characters are vbCrLf.
So for UNIX files:
myArray() = Split(TextFileData, vbLf)
And for old Mac files:
myArray() = Split(TextFileData, vbCr)

Decode base64 to RGB image in matlab

I am working in Matlab environment for a project, and I have to decode a RGB image received in xml from the database server, which is encoded in base64 format. I was successful in converting image to base64 and post it to the database by converting it into xml. I used the base64encode/decode to encode the image to base64 and I have attached the program below. The problem is when I use the base64decode function and try to reconvert the image from base64. It simply does not work.
This is my program for converting image to base64 and encode it in xml.
function image2xml(test_directory)
% Images in directory ---> byte array format in XML
% This function encodes all the images available in the test directory into
% byte array/base 64 format and saves them in xml with the following
% properties
% Packs the image(byte array) and its name as timestamp to xml
% Uses functions from the following source
% http://www.mathworks.de/matlabcentral/fileexchange/12907-xmliotools
% Following functions from the above source are to be added to path,while
% running this function
% xml_write.m
% xml_read.m
%% ========================================================================
files=dir(test_directory)
% delete('test_image_xml\*.xml');
% If not database_mat is included in the function arguments
for i = 1:size(files,1)
k=0;
if files(i).isdir()==0
%extracts name with which it savesa as xml
[~, name_to_save,~ ] = fileparts(files(i).name)
filename = fullfile([test_directory,'\',files(i).name])
fid = fopen(filename);
raw_data = uint8(fread(fid));% read image file as a raw binary
fclose(fid);
%Definition of xml tags
image_imagedetails = [];
% name of the file is assumed to be the timestamp
image_imagedetails.timestamp =name_to_save;
%imagescan.imagebyte64.ATTRIBUTE.EncodingMIMEType = 'base64';
image_imagedetails.imagebase64 = base64encode(raw_data);% perform base64 encoding of the binary data
%saves all the xml files into the predefined directory
mkdir('images_and_timestamp_xml');
filename = ['images_and_timestamp_xml\' name_to_save,'.xml' ];
post_data = xml_write(filename, image_imagedetails);
end
end
Finaly I use the following to reconvert the xml created with image in base64 format back to image, but unfortunately it does not work, and throws some strange characters, which I am not able to convert back into a image. I further have no clue as of how to convert the string back to image as well.
filename = '...\IMAG0386.xml';
tree = xml_read(filename);
image = tree.imagebase64;
K = base64decode(tree.imagebase64)) %test image retrieval --> only the string
And I tried out other option like using the Java code in matlab, but I do not know, how to use the code in matlab. There are many options in C#, Java, but I have no idea, as how to use them in matlab. Please help me in this regards.
I ran your code under Matlab R2012a and it seems to work as expected.
Maybe what is missing here is a few lines to get the image file back from the binary data encoded in base64. You just need to write the binary data to a file to get your image file back.
I am merely quoting the HTML help file from the Matlab FileExchange submission xmliotools that you are using in your code:
Read XML file with embedded binary data encoded as Base64 (using java
version)
tree = xml_read('test.xml', Pref); % read xml file
raw = base64decode(tree.MyImage.CONTENT, '', 'java'); % convert xml image to raw binary
fid = fopen('MyFootball.jpg', 'wb');
fwrite(fid, raw, 'uint8'); % dumb the raw binary to the hard disk
fclose(fid);
I = imread('MyFootball.jpg'); % read it as an image
imshow(I);
Simple Base64 Handling
Using the Apache library
base64 = org.apache.commons.codec.binary.Base64
Then you can call encode or decode.
base64.encode()
base64.decode()
It expects byte[], so you can get this in a couple of ways. Let's encode a string and then decode it.
hello = 'Hello, world!';
encoded = char(base64.encode(unicode2native(hello))).';
result = native2unicode(base64.decode(uint8(output)).');

problem with parsing string from excel file

i have ruby code to parse data in excel file using Parseexcel gem. I need to save 2 columns in that file into a Hash, here is my code:
worksheet.each { |row|
if row != nil
key = row.at(1).to_s.strip
value = row.at(0).to_s.strip
if !parts.has_key?(key) and key.length > 0
parts[key] = value
end
end
}
however it still save duplicate keys into the hash: "020098-10". I checked the excel file at the specified row and found the difference are " 020098-10" and "020098-10". the first one has a leading space while the second doesn't. I dont' understand is it true that .strip function already remove all leading and trailing white space?
also when i tried to print out key.length, it gave me these weird number:
020098-10 length 18
020098-10 length 17
which should be 9....
If you will inspect the strings you receive, you will probably get something like:
" \x000\x002\x000\x000\x009\x008\x00-\x001\x000\x00"
This happens because of the strings encoding. Excel works with unicode while ruby uses ISO-8859-1 by default. The encodings will differ on various platforms.
You need to convert the data you receive from excel to a printable encoding.
However when you should not encode strings created in ruby as you will end with garbage.
Consider this code:
#enc = Encoding::Converter.new("UTF-16LE", "UTF-8")
def convert(cell)
if cell.numeric
cell.value
else
#enc.convert(cell.value).strip
end
end
parts = {}
worksheet.each do |row|
continue unless row
key = convert row.at(1)
value = convert row.at(0)
parts[key] = value unless parts.has_key?(key) or key.empty?
end
You may want change the encodings to a different ones.
The newer Spreadsheet-gem handles charset conversion automatically for you, to UTF-8 I think as standard but you can change it, so I'd recommend using it instead.

Resources