由 DelphiZXingQRCode 编码的 QR 码无法通过 ErrorCorrectionLevel > Low 解码
QR Codes encoded by DelphiZXingQRCode not decodable with ErrorCorrectionLevel > Low
我正在使用这个 Delphi-Unit。我被迫使用这个旧的 Delphi 实现,所以不要问这个:
https://github.com/foxitsoftware/DelphiZXingQRCode
只要我将纠错级别保持在"Low",它生成的二维码就可以被任何解码器解码。如果我提高纠错级别,生成的代码将无法被我目前尝试过的任何解码器解码。但是我(按标准)被迫使用中等纠错级别,不多也不少。
但是不清楚如何提高纠错级别(从现在开始是ecl)。我假设它被硬编码在文件 DelphiZXingQRCode 的第 3491 行:Level.FBits := 1。我找到了一些关于代表 ecls 的 hexnumbers 的信息,但我现在找不到了。但我尝试将这些十六进制数字作为位,QRcode 上的 ecl 位相应地发生了变化。所以我假设十六进制数是正确的(1=低,0=中,2=高,3=四分位数)。
这是一个带有 Level.FBits := 2 的 QRcode 示例,这意味着我希望 ecl 为 "High"。内容是"Hello world"。中间的十字图像是我必须实施的标准 [原文如此] 的一部分,所以不要问这个。
有人知道如何解决这个问题吗?我试过……好吧……我试着理解代码,但它太多了。我无法修复它。如果我无法让其他人修复它,我将不得不……寻找其他解决方案。这将是一个问题。
已解决。请参阅下面的代码。方法 GenerateQRCode() 现在需要 ErrorCorrectionLevel 的参数:整数 0-3。似乎工作。我不得不删除一些未更改的行,因为该文件对于 Whosebug 来说太大了。合并自己。
unit DelphiZXingQRCode;
// ZXing QRCode port to Delphi, by Debenu Pty Ltd
// www.debenu.com
// Original copyright notice
(*
* Copyright 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*)
interface
type
TQRCodeEncoding = (qrAuto, qrNumeric, qrAlphanumeric, qrISO88591, qrUTF8NoBOM, qrUTF8BOM);
T2DBooleanArray = array of array of Boolean;
TDelphiZXingQRCode = class
protected
FData: WideString;
FRows: Integer;
FColumns: Integer;
FEncoding: TQRCodeEncoding;
FQuietZone: Integer;
FElements: T2DBooleanArray;
FErrorCorrectionLevel: integer;
procedure SetEncoding(NewEncoding: TQRCodeEncoding);
procedure SetData(const NewData: WideString);
procedure SetQuietZone(NewQuietZone: Integer);
procedure SetErrorCorrectionLevel(value: integer);
function GetIsBlack(Row, Column: Integer): Boolean;
procedure Update;
public
constructor Create;
property Data: WideString read FData write SetData;
property Encoding: TQRCodeEncoding read FEncoding write SetEncoding;
property ErrorCorrectionLevel: integer read fErrorCorrectionLevel write SetErrorCorrectionLevel;
property QuietZone: Integer read FQuietZone write SetQuietZone;
property Rows: Integer read FRows;
property Columns: Integer read FColumns;
property IsBlack[Row, Column: Integer]: Boolean read GetIsBlack;
end;
implementation
uses
SysUtils,
contnrs, Math, Classes;
type
TByteArray = array of Byte;
T2DByteArray = array of array of Byte;
TIntegerArray = array of Integer;
// File too large for Whosebug: Deleted unchanged lines.
{ TErrorCorrectionLevel }
procedure TErrorCorrectionLevel.Assign(Source: TErrorCorrectionLevel);
begin
Self.fOrdinal := Source.FOrdinal;
end;
constructor TErrorCorrectionLevel.Create(ordinalValue: integer);
begin
fOrdinal:=0;
if (ordinalValue >= 0) and (ordinalValue <=3) then
fOrdinal:=ordinalValue;
end;
function TErrorCorrectionLevel.GetBits: integer;
begin
if fOrdinal = 0 then // level L
result:=1
else
if fOrdinal = 1 then // level M
result:=0
else
if fOrdinal = 2 then // level Q
result:=3
else
if fOrdinal = 3 then // level H
result:=2
else
result:=1;
end;
// File too large for Whosebug: Deleted unchanged lines.
procedure TDelphiZXingQRCode.SetErrorCorrectionLevel(value: integer);
begin
if (value < 0) or (value > 3) then
raise Exception.Create('invalid error correction value. must be in range 0..3.');
if value <> fErrorCorrectionLevel then
begin
FErrorCorrectionLevel:=value;
Update;
end;
end;
procedure TDelphiZXingQRCode.SetQuietZone(NewQuietZone: Integer);
begin
if ((FQuietZone <> NewQuietZone) and (NewQuietZone >= 0) and (NewQuietZone <= 100)) then
begin
FQuietZone := NewQuietZone;
Update;
end;
end;
procedure TDelphiZXingQRCode.Update;
begin
FElements := GenerateQRCode(FData, Ord(FEncoding), FErrorCorrectionLevel);
FRows := Length(FElements) + FQuietZone * 2;
FColumns := FRows;
end;
end.
我正在使用这个 Delphi-Unit。我被迫使用这个旧的 Delphi 实现,所以不要问这个: https://github.com/foxitsoftware/DelphiZXingQRCode
只要我将纠错级别保持在"Low",它生成的二维码就可以被任何解码器解码。如果我提高纠错级别,生成的代码将无法被我目前尝试过的任何解码器解码。但是我(按标准)被迫使用中等纠错级别,不多也不少。
但是不清楚如何提高纠错级别(从现在开始是ecl)。我假设它被硬编码在文件 DelphiZXingQRCode 的第 3491 行:Level.FBits := 1。我找到了一些关于代表 ecls 的 hexnumbers 的信息,但我现在找不到了。但我尝试将这些十六进制数字作为位,QRcode 上的 ecl 位相应地发生了变化。所以我假设十六进制数是正确的(1=低,0=中,2=高,3=四分位数)。
这是一个带有 Level.FBits := 2 的 QRcode 示例,这意味着我希望 ecl 为 "High"。内容是"Hello world"。中间的十字图像是我必须实施的标准 [原文如此] 的一部分,所以不要问这个。
有人知道如何解决这个问题吗?我试过……好吧……我试着理解代码,但它太多了。我无法修复它。如果我无法让其他人修复它,我将不得不……寻找其他解决方案。这将是一个问题。
已解决。请参阅下面的代码。方法 GenerateQRCode() 现在需要 ErrorCorrectionLevel 的参数:整数 0-3。似乎工作。我不得不删除一些未更改的行,因为该文件对于 Whosebug 来说太大了。合并自己。
unit DelphiZXingQRCode;
// ZXing QRCode port to Delphi, by Debenu Pty Ltd
// www.debenu.com
// Original copyright notice
(*
* Copyright 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*)
interface
type
TQRCodeEncoding = (qrAuto, qrNumeric, qrAlphanumeric, qrISO88591, qrUTF8NoBOM, qrUTF8BOM);
T2DBooleanArray = array of array of Boolean;
TDelphiZXingQRCode = class
protected
FData: WideString;
FRows: Integer;
FColumns: Integer;
FEncoding: TQRCodeEncoding;
FQuietZone: Integer;
FElements: T2DBooleanArray;
FErrorCorrectionLevel: integer;
procedure SetEncoding(NewEncoding: TQRCodeEncoding);
procedure SetData(const NewData: WideString);
procedure SetQuietZone(NewQuietZone: Integer);
procedure SetErrorCorrectionLevel(value: integer);
function GetIsBlack(Row, Column: Integer): Boolean;
procedure Update;
public
constructor Create;
property Data: WideString read FData write SetData;
property Encoding: TQRCodeEncoding read FEncoding write SetEncoding;
property ErrorCorrectionLevel: integer read fErrorCorrectionLevel write SetErrorCorrectionLevel;
property QuietZone: Integer read FQuietZone write SetQuietZone;
property Rows: Integer read FRows;
property Columns: Integer read FColumns;
property IsBlack[Row, Column: Integer]: Boolean read GetIsBlack;
end;
implementation
uses
SysUtils,
contnrs, Math, Classes;
type
TByteArray = array of Byte;
T2DByteArray = array of array of Byte;
TIntegerArray = array of Integer;
// File too large for Whosebug: Deleted unchanged lines.
{ TErrorCorrectionLevel }
procedure TErrorCorrectionLevel.Assign(Source: TErrorCorrectionLevel);
begin
Self.fOrdinal := Source.FOrdinal;
end;
constructor TErrorCorrectionLevel.Create(ordinalValue: integer);
begin
fOrdinal:=0;
if (ordinalValue >= 0) and (ordinalValue <=3) then
fOrdinal:=ordinalValue;
end;
function TErrorCorrectionLevel.GetBits: integer;
begin
if fOrdinal = 0 then // level L
result:=1
else
if fOrdinal = 1 then // level M
result:=0
else
if fOrdinal = 2 then // level Q
result:=3
else
if fOrdinal = 3 then // level H
result:=2
else
result:=1;
end;
// File too large for Whosebug: Deleted unchanged lines.
procedure TDelphiZXingQRCode.SetErrorCorrectionLevel(value: integer);
begin
if (value < 0) or (value > 3) then
raise Exception.Create('invalid error correction value. must be in range 0..3.');
if value <> fErrorCorrectionLevel then
begin
FErrorCorrectionLevel:=value;
Update;
end;
end;
procedure TDelphiZXingQRCode.SetQuietZone(NewQuietZone: Integer);
begin
if ((FQuietZone <> NewQuietZone) and (NewQuietZone >= 0) and (NewQuietZone <= 100)) then
begin
FQuietZone := NewQuietZone;
Update;
end;
end;
procedure TDelphiZXingQRCode.Update;
begin
FElements := GenerateQRCode(FData, Ord(FEncoding), FErrorCorrectionLevel);
FRows := Length(FElements) + FQuietZone * 2;
FColumns := FRows;
end;
end.