検索
ホームページJava&#&チュートリアルAndroidはGoogle Zxingに基づいたさまざまなQRコードスキャン効果を実装しています

WeChat の登場により、ショッピング モール、KFC、レストランなど、どこでも QR コードを見かけるようになりました。QR コードのスキャンには、Google のオープンソース フレームワーク Zxing を使用します。 http://code.google.com/p/zxing/ にアクセスして、ソース コードと Jar パッケージをダウンロードします。以前は、私のプロジェクトの QR コード スキャン機能はスキャン機能のみを実装していましたが、その UI は非常に醜いものでした。したがって、アプリケーション ソフトウェアの機能は、インターフェイスと同じくらい重要であり、多くのアプリケーション ソフトウェアによって模倣されていると思います。私も WeChat で QR コードをスキャンする効果を真似ています。WeChat ほど洗練されていませんが、それでも効果は良好です。そこで、UI を変更するコードと、QR コードをスキャンするコードを共有します。 QR コード。1 つ目は、この機能を直接コピーして使用できることです。2 つ目は、まだ QR コード機能を追加していない人に参考にすることです。笑 次に、この機能を追加する前に、多くの不要なファイルを削除します。この関数をプロジェクトに追加するには、 com.mining.app.zxing.camera 、 com.mining.app.zxing.decoding、 com.mining.app.zxing.view を直接追加し、これら 3 つのパッケージをプロジェクトにコピーします。対応するリソースをプロジェクトから直接引用しましたが、もちろん、Zxing.jar

パッケージを参照する必要があります。その中にある MipcaActivityCapture も、以前のプロジェクトのコードを直接導入しています。このアクティビティは、主にスキャン インターフェイス クラスを処理します。たとえば、スキャンが成功すると音や振動が発生します。主に handleDecode(Result) に焦点を当てます。 result, Bitmap barcode) メソッド。スキャンが完了すると、スキャン結果と QR コードの元のビットマップ パラメーターが handleDecode(Result result, Bitmap barcode) に渡されます。それに対応する処理コードを記述するだけです。他の場所を変更する必要はありません。ここではスキャン結果とスキャンによって撮影された写真を処理します

/** 
 * 处理扫描结果 
 * @param result 
 * @param barcode 
 */
public void handleDecode(Result result, Bitmap barcode) { 
  inactivityTimer.onActivity(); 
  playBeepSoundAndVibrate(); 
  String resultString = result.getText(); 
  if (resultString.equals("")) { 
    Toast.makeText(MipcaActivityCapture.this, "Scan failed!", Toast.LENGTH_SHORT).show(); 
  }else { 
    Intent resultIntent = new Intent(); 
    Bundle bundle = new Bundle(); 
    bundle.putString("result", resultString); 
    bundle.putParcelable("bitmap", barcode); 
    resultIntent.putExtras(bundle); 
    this.setResult(RESULT_OK, resultIntent); 
  } 
  MipcaActivityCapture.this.finish(); 
}
Android基于google Zxing实现各类二维码扫描效果主に FrameLayout を使用して、MipcaActivityCapture インターフェイスのレイアウトを独自に変更しました。 RelativeLayout が内部にネストされています。

レイアウトコードは以下の通りです

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
    android:layout_height="fill_parent" > 
  
  <RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" > 
  
    <SurfaceView
      android:id="@+id/preview_view"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:layout_gravity="center" /> 
  
    <com.mining.app.zxing.view.ViewfinderView
      android:id="@+id/viewfinder_view"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" /> 
  
    <include
      android:id="@+id/include1"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_alignParentTop="true"
      layout="@layout/activity_title" /> 
  </RelativeLayout> 
  
</FrameLayout>

その中で、インターフェースの上部を別のレイアウトで書いてインクルードしました。この activity_title はプロジェクト内の他のアクティビティでも使用されているため、これも直接コピーしました

。私のデモでは、ボタン、ImageView、および TextView を備えたメイン インターフェイス MainActivity があり、ボタンをクリックして QR コード スキャン インターフェイスに入り、スキャンが OK になったら、メイン インターフェイスに戻り、スキャン結果を表示します。 ImageView に画像を表示すると、ここで画像を追加する必要はありません。メイン インターフェイスのレイアウトは次のとおりです。MainActivity のコードは次のとおりです。 、内部の関数は上で説明されています

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:background="@drawable/mmtitle_bg_alpha" > 
  
  <Button
    android:id="@+id/button_back"
    android:layout_width="75.0dip"
    android:text="返回"
    android:background="@drawable/mm_title_back_btn"
    android:textColor="@android:color/white"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_marginLeft="2dip" /> 
  
  <TextView
    android:id="@+id/textview_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@+id/button_back"
    android:layout_alignBottom="@+id/button_back"
    android:layout_centerHorizontal="true"
    android:gravity="center_vertical"
    android:text="二维码扫描"
    android:textColor="@android:color/white"
    android:textSize="18sp" /> 
  
</RelativeLayout>

上 コードはまだ比較的単純ですが、WeChat のようなスキャン ボックスを作成したい場合、上記のコードにはそのような効果はありません。com の下にある ViewfinderView クラスを書き直す必要があります。 .mining.app.zxing.view パッケージ。コードのコメントはすべて私が作成したものです。コードを変更したい場合は理解できると思います。スキャン フレームのサイズを変更するには、CameraManager クラスに移動して変更します

上記のコードで、中央の行は WeChat で使用される画像です。よりシミュレートしたい場合は、次のコードを変更します。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#ffe1e0de" > 
  
  <Button
    android:id="@+id/button1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:text="扫描二维码" /> 
  
  <TextView
    android:id="@+id/result"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/button1"
    android:lines="2"
    android:gravity="center_horizontal"
    android:textColor="@android:color/black"
    android:textSize="16sp" /> 
  
  <ImageView
    android:id="@+id/qrcode_bitmap"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/result"/> 
</RelativeLayout>

から

package com.example.qr_codescan; 
  
  
import android.app.Activity; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.TextView; 
  
public class MainActivity extends Activity { 
  private final static int SCANNIN_GREQUEST_CODE = 1; 
  /** 
   * 显示扫描结果 
   */
  private TextView mTextView ; 
  /** 
   * 显示扫描拍的图片 
   */
  private ImageView mImageView; 
    
  
  @Override
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
      
    mTextView = (TextView) findViewById(R.id.result);  
    mImageView = (ImageView) findViewById(R.id.qrcode_bitmap); 
      
    //点击按钮跳转到二维码扫描界面,这里用的是startActivityForResult跳转 
    //扫描完了之后调到该界面 
    Button mButton = (Button) findViewById(R.id.button1); 
    mButton.setOnClickListener(new OnClickListener() { 
        
      @Override
      public void onClick(View v) { 
        Intent intent = new Intent(); 
        intent.setClass(MainActivity.this, MipcaActivityCapture.class); 
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
        startActivityForResult(intent, SCANNIN_GREQUEST_CODE); 
      } 
    }); 
  } 
    
    
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    switch (requestCode) { 
    case SCANNIN_GREQUEST_CODE: 
      if(resultCode == RESULT_OK){ 
        Bundle bundle = data.getExtras(); 
        //显示扫描到的内容 
        mTextView.setText(bundle.getString("result")); 
        //显示 
        mImageView.setImageBitmap((Bitmap) data.getParcelableExtra("bitmap")); 
      } 
      break; 
    } 
  }   
  
}

そのスキャン WeChatにアクセスして自分で探してください、私が投稿したものは歪んでいます、サフィックス名をzipに変更してから解凍してください。文字が長すぎる場合は、フォントに合わせて自動的に配置されるように、描画スキャン ボックスの下のフォントを変更する必要があります。これには、自動行折り返しが必要です。自分で処理してください

/* 
 * Copyright (C) 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 
 * 
 *   * 
 * 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. 
 */ 
  
package com.mining.app.zxing.view; 
  
import java.util.Collection; 
import java.util.HashSet; 
  
import android.content.Context; 
import android.content.res.Resources; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.graphics.Typeface; 
import android.util.AttributeSet; 
import android.view.View; 
  
import com.example.qr_codescan.R; 
import com.google.zxing.ResultPoint; 
import com.mining.app.zxing.camera.CameraManager; 
  
/** 
 * This view is overlaid on top of the camera preview. It adds the viewfinder 
 * rectangle and partial transparency outside it, as well as the laser scanner 
 * animation and result points. 
 * 
 */ 
public final class ViewfinderView extends View { 
  private static final String TAG = "log"; 
  /** 
   * 刷新界面的时间 
   */ 
  private static final long ANIMATION_DELAY = 10L; 
  private static final int OPAQUE = 0xFF; 
  
  /** 
   * 四个绿色边角对应的长度 
   */ 
  private int ScreenRate; 
    
  /** 
   * 四个绿色边角对应的宽度 
   */ 
  private static final int CORNER_WIDTH = 10; 
  /** 
   * 扫描框中的中间线的宽度 
   */ 
  private static final int MIDDLE_LINE_WIDTH = 6; 
    
  /** 
   * 扫描框中的中间线的与扫描框左右的间隙 
   */ 
  private static final int MIDDLE_LINE_PADDING = 5; 
    
  /** 
   * 中间那条线每次刷新移动的距离 
   */ 
  private static final int SPEEN_DISTANCE = 5; 
    
  /** 
   * 手机的屏幕密度 
   */ 
  private static float density; 
  /** 
   * 字体大小 
   */ 
  private static final int TEXT_SIZE = 16; 
  /** 
   * 字体距离扫描框下面的距离 
   */ 
  private static final int TEXT_PADDING_TOP = 30; 
    
  /** 
   * 画笔对象的引用 
   */ 
  private Paint paint; 
    
  /** 
   * 中间滑动线的最顶端位置 
   */ 
  private int slideTop; 
    
  /** 
   * 中间滑动线的最底端位置 
   */ 
  private int slideBottom; 
    
  private Bitmap resultBitmap; 
  private final int maskColor; 
  private final int resultColor; 
    
  private final int resultPointColor; 
  private Collection<ResultPoint> possibleResultPoints; 
  private Collection<ResultPoint> lastPossibleResultPoints; 
  
  boolean isFirst; 
    
  public ViewfinderView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
      
    density = context.getResources().getDisplayMetrics().density; 
    //将像素转换成dp 
    ScreenRate = (int)(20 * density); 
  
    paint = new Paint(); 
    Resources resources = getResources(); 
    maskColor = resources.getColor(R.color.viewfinder_mask); 
    resultColor = resources.getColor(R.color.result_view); 
  
    resultPointColor = resources.getColor(R.color.possible_result_points); 
    possibleResultPoints = new HashSet<ResultPoint>(5); 
  } 
  
  @Override 
  public void onDraw(Canvas canvas) { 
    //中间的扫描框,你要修改扫描框的大小,去CameraManager里面修改 
    Rect frame = CameraManager.get().getFramingRect(); 
    if (frame == null) { 
      return; 
    } 
      
    //初始化中间线滑动的最上边和最下边 
    if(!isFirst){ 
      isFirst = true; 
      slideTop = frame.top; 
      slideBottom = frame.bottom; 
    } 
      
    //获取屏幕的宽和高 
    int width = canvas.getWidth(); 
    int height = canvas.getHeight(); 
  
    paint.setColor(resultBitmap != null ? resultColor : maskColor); 
      
    //画出扫描框外面的阴影部分,共四个部分,扫描框的上面到屏幕上面,扫描框的下面到屏幕下面 
    //扫描框的左边面到屏幕左边,扫描框的右边到屏幕右边 
    canvas.drawRect(0, 0, width, frame.top, paint); 
    canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint); 
    canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, 
        paint); 
    canvas.drawRect(0, frame.bottom + 1, width, height, paint); 
      
      
  
    if (resultBitmap != null) { 
      // Draw the opaque result bitmap over the scanning rectangle 
      paint.setAlpha(OPAQUE); 
      canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint); 
    } else { 
  
      //画扫描框边上的角,总共8个部分 
      paint.setColor(Color.GREEN); 
      canvas.drawRect(frame.left, frame.top, frame.left + ScreenRate, 
          frame.top + CORNER_WIDTH, paint); 
      canvas.drawRect(frame.left, frame.top, frame.left + CORNER_WIDTH, frame.top 
          + ScreenRate, paint); 
      canvas.drawRect(frame.right - ScreenRate, frame.top, frame.right, 
          frame.top + CORNER_WIDTH, paint); 
      canvas.drawRect(frame.right - CORNER_WIDTH, frame.top, frame.right, frame.top 
          + ScreenRate, paint); 
      canvas.drawRect(frame.left, frame.bottom - CORNER_WIDTH, frame.left 
          + ScreenRate, frame.bottom, paint); 
      canvas.drawRect(frame.left, frame.bottom - ScreenRate, 
          frame.left + CORNER_WIDTH, frame.bottom, paint); 
      canvas.drawRect(frame.right - ScreenRate, frame.bottom - CORNER_WIDTH, 
          frame.right, frame.bottom, paint); 
      canvas.drawRect(frame.right - CORNER_WIDTH, frame.bottom - ScreenRate, 
          frame.right, frame.bottom, paint); 
  
        
      //绘制中间的线,每次刷新界面,中间的线往下移动SPEEN_DISTANCE 
      slideTop += SPEEN_DISTANCE; 
      if(slideTop >= frame.bottom){ 
        slideTop = frame.top; 
      } 
      canvas.drawRect(frame.left + MIDDLE_LINE_PADDING, slideTop - MIDDLE_LINE_WIDTH/2, frame.right - MIDDLE_LINE_PADDING,slideTop + MIDDLE_LINE_WIDTH/2, paint); 
        
        
      //画扫描框下面的字 
      paint.setColor(Color.WHITE); 
      paint.setTextSize(TEXT_SIZE * density); 
      paint.setAlpha(0x40); 
      paint.setTypeface(Typeface.create("System", Typeface.BOLD)); 
      canvas.drawText(getResources().getString(R.string.scan_text), frame.left, (float) (frame.bottom + (float)TEXT_PADDING_TOP *density), paint); 
        
        
  
      Collection<ResultPoint> currentPossible = possibleResultPoints; 
      Collection<ResultPoint> currentLast = lastPossibleResultPoints; 
      if (currentPossible.isEmpty()) { 
        lastPossibleResultPoints = null; 
      } else { 
        possibleResultPoints = new HashSet<ResultPoint>(5); 
        lastPossibleResultPoints = currentPossible; 
        paint.setAlpha(OPAQUE); 
        paint.setColor(resultPointColor); 
        for (ResultPoint point : currentPossible) { 
          canvas.drawCircle(frame.left + point.getX(), frame.top 
              + point.getY(), 6.0f, paint); 
        } 
      } 
      if (currentLast != null) { 
        paint.setAlpha(OPAQUE / 2); 
        paint.setColor(resultPointColor); 
        for (ResultPoint point : currentLast) { 
          canvas.drawCircle(frame.left + point.getX(), frame.top 
              + point.getY(), 3.0f, paint); 
        } 
      } 
  
        
      //只刷新扫描框的内容,其他地方不刷新 
      postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, 
          frame.right, frame.bottom); 
        
    } 
  } 
  
  public void drawViewfinder() { 
    resultBitmap = null; 
    invalidate(); 
  } 
  
  /** 
   * Draw a bitmap with the result points highlighted instead of the live 
   * scanning display. 
   * 
   * @param barcode 
   *      An image of the decoded barcode. 
   */
  public void drawResultBitmap(Bitmap barcode) { 
    resultBitmap = barcode; 
    invalidate(); 
  } 
  
  public void addPossibleResultPoint(ResultPoint point) { 
    possibleResultPoints.add(point); 
  } 
  
}

インターフェースのスクリーンショットを実行すると、WeChat と同様の効果が得られます。もちろん、対応する権限の問題もそのまま実行できます。必須。

上記がこの記事の全内容です。Android ソフトウェア プログラミングを学習している皆様のお役に立てれば幸いです。

Google Zxing に基づくさまざまな QR コード スキャン効果の実現に関する Android ベースの記事については、PHP 中国語 Web サイトに注目してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Java開発のどの側面がプラットフォームに依存していますか?Java開発のどの側面がプラットフォームに依存していますか?Apr 26, 2025 am 12:19 AM

javadevelopmentisnotentirelylylypratform-IndopentDuetoseveralfactors.1)jvmvariationsaffectperformanceandbehavioracrossdifferentos.2)nativeLibrariesviajniintroducePlatform-specificissues.3)giaiasystemsdifferbeTioneplateplatifflics.4)

さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?Apr 26, 2025 am 12:15 AM

Javaコードは、さまざまなプラットフォームで実行するときにパフォーマンスの違いがあります。 1)JVMの実装と最適化戦略は、OracleJDKやOpenJDKなどとは異なります。 2)メモリ管理やスレッドスケジューリングなどのオペレーティングシステムの特性もパフォーマンスに影響します。 3)適切なJVMを選択し、JVMパラメーターとコード最適化を調整することにより、パフォーマンスを改善できます。

Javaのプラットフォームの独立性の制限は何ですか?Javaのプラットフォームの独立性の制限は何ですか?Apr 26, 2025 am 12:10 AM

java'splatformindepentedencehaslimitationsincludingporformanceoverhead、versioncompatibulisisues、changleSwithnativeLibraryIntegration、プラットフォーム固有の機能、およびjvminStallation/maintenation。

プラットフォームの独立性とクロスプラットフォーム開発の違いを説明します。プラットフォームの独立性とクロスプラットフォーム開発の違いを説明します。Apr 26, 2025 am 12:08 AM

PlatformEndependEncealLowsProgramStorunonAnyPlatformWithOdification、whilecross-platformdevelopmentReadreessomeplatform-specificAdjustments.platformindependence、explifiedByjava、unableSiversAlexecutionButMayCompromperformance

ジャストインタイム(JIT)コンピレーションは、Javaのパフォーマンスとプラットフォームの独立性にどのような影響を与えますか?ジャストインタイム(JIT)コンピレーションは、Javaのパフォーマンスとプラットフォームの独立性にどのような影響を与えますか?Apr 26, 2025 am 12:02 AM

jitcompalilationinjavaenhancesperformance whelemaintaining formindepence.1)itdynamicallyTrantesiNTODENATIVEMACHINECODEATRUNTIME、最適化されたコードを最適化すること、

Javaがクロスプラットフォームデスクトップアプリケーションを開発するための人気のある選択肢なのはなぜですか?Javaがクロスプラットフォームデスクトップアプリケーションを開発するための人気のある選択肢なのはなぜですか?Apr 25, 2025 am 12:23 AM

javaispopularforsoss-platformdesktopapplicationsduetoits "writeonce、runaynay" philosophy.1)itusesbytecodatiTatrunnanyjvm-adipplatform.2)ライブラリリケンディンガンドジャヴァフククレアティック - ルルクリス

Javaでプラットフォーム固有のコードを作成する必要がある場合がある状況について話し合います。Javaでプラットフォーム固有のコードを作成する必要がある場合がある状況について話し合います。Apr 25, 2025 am 12:22 AM

Javaでプラットフォーム固有のコードを作成する理由には、特定のオペレーティングシステム機能へのアクセス、特定のハードウェアとの対話、パフォーマンスの最適化が含まれます。 1)JNAまたはJNIを使​​用して、Windowsレジストリにアクセスします。 2)JNIを介してLinux固有のハードウェアドライバーと対話します。 3)金属を使用して、JNIを介してMacOSのゲームパフォーマンスを最適化します。それにもかかわらず、プラットフォーム固有のコードを書くことは、コードの移植性に影響を与え、複雑さを高め、パフォーマンスのオーバーヘッドとセキュリティのリスクをもたらす可能性があります。

プラットフォームの独立性に関連するJava開発の将来の傾向は何ですか?プラットフォームの独立性に関連するJava開発の将来の傾向は何ですか?Apr 25, 2025 am 12:12 AM

Javaは、クラウドネイティブアプリケーション、マルチプラットフォームの展開、および言語間の相互運用性を通じて、プラットフォームの独立性をさらに強化します。 1)クラウドネイティブアプリケーションは、GraalvmとQuarkusを使用してスタートアップ速度を向上させます。 2)Javaは、埋め込みデバイス、モバイルデバイス、量子コンピューターに拡張されます。 3)Graalvmを通じて、JavaはPythonやJavaScriptなどの言語とシームレスに統合して、言語間の相互運用性を高めます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール