форум группы Chief-Net » » Программирование » Delphi 11 миграция

Страниц (1): [1]
 

1. Guyver - 08 Марта, 2023 - 05:20:45 - перейти к сообщению
Марат, подскажи. Я не очень понимаю почему в новой версии это не работает:

CODE:
function HEX2DEC(HEX: string): LONGINT;

function Digt(Ch: CHAR): BYTE;
const
HEXDigts: string[16] = '0123456789ABCDEF';
var
I: BYTE;
N: BYTE;
begin
N := 0;
for I := 1 to Length(HEXDigts) do
if Ch = HEXDigts[I] then
N := I - 1;
Digt := N;
end;

const
HEXSet: set of CHAR = ['0'..'9', 'A'..'F'];
var
J: LONGINT;
Error: BOOLEAN;
DEC: LONGINT;
begin
DEC := 0;
Error := False;
for J := 1 to Length(HEX) do
begin
if not (UpCase(HEX[J]) in HEXSet) then
Error := True;
DEC := DEC + Digt(UpCase(HEX[J])) shl ((Length(HEX) - J) * 4);
{ 16^N = 2^(N * 4) }
{ N SHL ((Length(HEX) - J) * 4) = N * 16^(Length(HEX) - J) }
end;
if Error then
HEX2DEC := 0
else
HEX2DEC := DEC;
end;


Ошибка здесь: if Ch = HEXDigts[I] then

Как изменить функцию, чтобы заработало?
2. Марат - 08 Марта, 2023 - 10:33:01 - перейти к сообщению
Delphi начиная с Delphi 2009 перешла на юникод. Теперь char равен 2 байтам от #0 до #$FFFF. String соотвественно тоже изменился, так как состоит из char и поддерживает длину строки до 2 Гигабайт.
Бывший string сейчас называется shortString. а бывший char сейчас AnsiChar.
У тебя String[16] а значит используется ShortString, который содержит символы AnsiChar, т.е. 8 битные. Ты наведи на тип переменной и увидишь подсказки.
Просто напиши так
CODE:
HEXDigts: string = '0123456789ABCDEF';
3. Guyver - 08 Марта, 2023 - 10:33:55 - перейти к сообщению
Спасибо.
4. Guyver - 12 Марта, 2023 - 04:59:40 - перейти к сообщению
Марат, не подскажешь функцию перевода bmp в 4bpp (SEGA). К примеру, есть у меня бмп размером 320*224 16-цветный (или лучше взять 24 битный или 256-цветный и потом написать bmp.PixelFormat:=pf4bit; ?). И я хочу его сохранить как bin.

Для палитры у меня отдельно есть 16 байт в файле bin (в нём помимо палитры есть код и сама картинка в формате 4bpp), которые я могу поменять потом как угодно. А вот само изображение как переконвертировать? Это надо оба формата разбирать. Вдруг у тебя есть готовый код...

Вижу, что если взять картинку 16-цветную бмп и убрать заголовок бмп - то размер будет такой же, как у файла 4bpp bin. Т.е. там тоже кодировка пикселя 4 байтами, но совсем другой формат пиксельных данных?
5. Guyver - 14 Марта, 2023 - 03:16:42 - перейти к сообщению


Для 16-цветного bmp (буду работать с ним, конвертируя в него другие форматы при необходимости) формат такой:

biBitCount 4
Максимально возможное количество цветов 16
Палитровый формат
Каждый байт описывает 2 пикселя. В байте младшая часть - цвет первого пикселя, старшая - второго. Цвет из палитры по номеру от 0 до F.

палитра:

0 чёрный
1 тёмно-красный
2 тёмно-зелёный
3 коричневый
4 тёмно-синий
5 тёмно-фиолетовый
6 бирюзовый
7 тёмно-серый
8 серый
9 красный
A зелёный
B желтый
C синий
D фиолетовый
E голубой
F белый

16-цветная картинка 32х1 пиксель весом 134 байта.

адрес 00: первые 2 байта от слова BitMap (BM) 424D
адрес 02: Потом размер файла в байтах - 86 (134 байта)
адрес 0A: Адрес начала карты пикселей (h76)
адрес 0E: размер заголовка картинки (28) 40 байт
адрес 12: ширина изображения (20) 32 пискеля
адрес 16: высота изображения (01) 1 пиксель
адрес 1A: количество плоскостей (01)
адрес 1С: (04) бит на пиксель

Карта пикселей - находится в конце файла, выделена голубым цветом. В теории палитра из файла не нужна, она всегда одинаковая, нужна только карта пикселей... Размер картинки у меня будет всегда одинаковый.

Вот теперь такое же описание бы для формата 4BPP MSX (Genesis), чтобы написать функцию для переконвертирования карты пикселей 4-битного bmp в этот формат...

Как я понимаю, там изображение составляется не слева-направо, а тайлами? По 64 бита в каждом... Какой план действий? Прочитать карту пикселей в массив и по формуле переформатировать массив, а потом сохранить его?
6. Guyver - 14 Марта, 2023 - 05:00:35 - перейти к сообщению
карта пикселей bmp:

0000 0001 0002 0003 0004 0005 0006 0007
1000 1001 1002 1003 1004 1005 1006 1007
2000 2001 2002 2003 2004 2005 2006 2007
3000 3001 3002 3003 3004 3005 3006 3007
4000 4001 4002 4003 4004 4005 4006 4007
5000 5001 5002 5003 5004 5005 5006 5007
6000 6001 6002 6003 6004 6005 6006 6007
7000 7001 7002 7003 7004 7005 7006 7007

карта пикселей smd:

0000 1000 2000 3000 4000 5000 6000 7000
0001 1001 2001 3001 4001 5001 6001 7001
0002 1002 2002 3002 4002 5002 6002 7002
0003 1003 2003 3003 4003 5003 6003 7003
0004 1004 2004 3004 4004 5004 6004 7004
0005 1005 2005 3005 4005 5005 6005 7005
0006 1006 2006 3006 4006 5006 6006 7006
0007 1007 2007 3007 4007 5007 6007 7007

Так? Т.е. через каждые 64 бита нужно "строки" поменять местами со "столбцами"?
7. Марат - 14 Марта, 2023 - 06:55:07 - перейти к сообщению
CODE:
procedure ConvertDataToBitmap(Data: TBytes; Bitmap: TBitmap);
const
tileWidth = 8;
tileHeight = 8;

var
p: PByteArray;
tilesInRow, tilesInColumn: Integer;
x, y, i, j: Integer;
dataSize: Integer;
begin
tilesInRow := Bitmap.Height div tileHeight;
tilesInColumn := Bitmap.Width div tileWidth;
dataSize := Length(Data);

for i := 0 to tilesInRow - 1 do
begin
for j := 0 to tilesInColumn - 1 do
begin
for y := 0 to tileHeight - 1 do
begin
p := Bitmap.ScanLine[i * tileHeight + y];
for x := 0 to (tileWidth div 2) - 1 do
begin
p[j * tileWidth + x] := Data[i * 32 * tilesInColumn + j * 32 + y * tileWidth + x];
end;
end;
end;
end;
end;

Примерно так, если я ничего не напутал. Только это больше подходит для GBA. А у smd надо тетрады в байте поменять местами
8. Guyver - 14 Марта, 2023 - 15:48:54 - перейти к сообщению
Не получается:



Как я только не пробовал. Прикол в том, что картинка получается мало того, что не до конца правильная, так и ещё задом-наперёд. Что странно, так как опытным путём вроде бы алгоритм понятен, но реализовать его не получается...

Найти бы где-то расшифровку алгоритма, как бмп...
9. Марат - 14 Марта, 2023 - 15:57:57 - перейти к сообщению
Что-то такое я припоминаю, то ли с Хорором, то ли с Гривером много лет назад обсуждал этот момент, что картинка перевёрнутая получается. Это если напрямую пытаться её менять, а если, как я показывал через ScanLine, то все правильно должно быть. А так, она вроде отзеркалена и по вертикали и по горизонтали
10. Марат - 14 Марта, 2023 - 16:01:44 - перейти к сообщению
Вот примерно во так лежат пиксели в битмапа, как здесь png у lupus http://www.emu-land.net/forum/in...pic,86390.0.html
11. Guyver - 14 Марта, 2023 - 16:57:31 - перейти к сообщению
Ну, файл задом-наперёд я поворачиваю без проблем, но вот сам алгоритм пока не пойму. Читаю из файла побайтно и записываю в файл тоже побайтно, но в другом порядке...
12. Марат - 14 Марта, 2023 - 17:29:00 - перейти к сообщению
Вот этот код полность рабочий, я проверил

CODE:
procedure ConvertDataToBitmap(Data: TBytes; Bitmap: TBitmap);
const
tileWidth = 8;
tileHeight = 8;

var
p: PByteArray;
tilesInRow, tilesInColumn: Integer;
x, y, i, j: Integer;
dataSize: Integer;
begin
tilesInRow := Bitmap.Height div tileHeight;
tilesInColumn := Bitmap.Width div tileWidth;
dataSize := Length(Data);

for i := 0 to tilesInRow - 1 do
begin
for j := 0 to tilesInColumn - 1 do
begin
for y := 0 to tileHeight - 1 do
begin
p := Bitmap.ScanLine[i * tileHeight + y];
for x := 0 to (tileWidth div 2) - 1 do
begin
p[j * (tileWidth div 2) + x] := Data[i * 32 * tilesInColumn + j * 32 + y * tileWidth div 2 + x];
end;
end;
end;
end;
end;
13. Guyver - 14 Марта, 2023 - 17:30:58 - перейти к сообщению
Спасибо. Я, кажется, нашёл ошибку в своём коде. Если не разберусь - попробую твой...

UPDT: ошибку действительно нашёл, всё что хотел - сделал вроде...
14. Марат - 29 Марта, 2023 - 21:23:15 - перейти к сообщению
Сегодня узнал, что теперь в дельфи можно писать так:
CODE:

var
MyString: String;
MyStringLength: Integer;
MyStringLowerCase: String;
begin
MyString := 'Hello World!';
MyStringLength := MyString.Length;
MyStringLowerCase := MyString.ToLower;

// И даже так

MyStringLength := MyString.ToLower.ToUpper.Length;

//и ещё десятки функци манипулирования со строкой и десятки свойств.
//По сути всё что есть в C# для работы со строкой доступно и для Дельфи
end;




Пример, как я переписал с C# на Дельфи.







15. Guyver - 30 Марта, 2023 - 00:38:25 - перейти к сообщению
Эх... А я так си не люблю (особенно чистый). Универ отбил всю любовь 😄
16. Марат - 30 Марта, 2023 - 04:39:59 - перейти к сообщению
Ну c# это самостоятельной язык тем более его разрабатывал создатель turbo pascal и delphi.
17. Марат - 30 Марта, 2023 - 05:18:38 - перейти к сообщению
Guyver пишет:
Эх... А я так си не люблю (особенно чистый). Универ отбил всю любовь 😄


Я бы из c синтаксиса взял ещё присваивания типа +=, -=, ++, --.
А вообще удобно же писать MyString.Length, чем Length(MyString).
Я бы такое ещё для массивов сделал, хотя бы для динамических.
И ещё удобство в том, что после точки у тебя весь список доступных методов со строкой выходит, а то сидишь и вспоминаешь какие функции есть для работы со строкой. Постоянно приходится лезть в Гугл.
18. Griever - 30 Марта, 2023 - 20:58:23 - перейти к сообщению
Цитата:
Пример, как я переписал с C# на Дельфи.

На шарпе это вообще одна строка
CODE:
string ext = Path.GetExtension(myFilePath);

Ха-ха
Да, stringBuilder, isNullOrEmpty подозрительно похож на .net
По идеологии, кстати, C# - это перелицованная Java
19. Марат - 30 Марта, 2023 - 22:44:12 - перейти к сообщению
Да нет, ты не понял.
Здесь все расширения плагинов собираются в одну строку для All Files;

А так-то и на дельфи есть ExtractFileExt(filename);

Griever пишет:
Да, stringBuilder, isNullOrEmpty подозрительно похож на .net
По идеологии, кстати, C# - это перелицованная Java


Да там много чего из нет. TFile аналог File в net, TEncoding аналог Encoding.
Но это не удивительно ведь они у них был раньше Delphi for .net;
20. Марат - 30 Марта, 2023 - 22:46:11 - перейти к сообщению
Griever пишет:
На шарпе это вообще одна строка


В дельфи, кстати, тоже есть такое

Цитата:
System.IOUtils.TPath.GetExtension

Up to Parent: TPath

Delphi

class function GetExtension(const FileName: string): string; static;


Powered by ExBB
ExBB FM 1.0 RC1 by TvoyWeb.ru
InvisionExBB Style converted by Markus®